- Home /
Cooldown on a spell, and make full animation.
What is the best way to make a cooldown system, so the spell first can be casted when it's ready? At the same time I want the "punch" animation to be done, before it stops. The spell input is at line 450
var jumpSpeed:float = 9.0;
private var gravity:float = 20.0;
static var runSpeed:float = 10;
static var swimSpeed:float = 2.0;
static var walkSpeed:float = 3;
static var runSpeedsave = 5.0;
static var walkSpeedsave = 2;
static var curSpeed:float = 0.0;
private var rotateSpeed:float = 150.0;
private var grounded:boolean = false;
private var moveDirection:Vector3 = Vector3.zero;
static var isWalking:boolean = false;
private var moveStatus:String = "idle";
private var xSpeed = 250.0;
private var ySpeed = 120.0;
private var yMinLimit = -40;
private var yMaxLimit = 80;
private var x = 0.0;
private var y = 0.0;
static var ddistance:float = 0.0;
static var strafemod:Vector3 = Vector3.zero;
static var strafing = false;
static var animationspeed = 1.0;
var hit : RaycastHit;
static var isSwimming = false;
static var bmove = false;
static var bSpeed = 0.0;
//UPDATE
//
function Update ()
//check if we fell down the world and teleport to a specific location
{
if(transform.position.y < -200)
{
transform.position.y = 16.07609;
transform.position.x = 579.2826;
transform.position.z = 130.8261;
}
//Move controller
var controller:CharacterController = GetComponent(CharacterController);
var flags = controller.Move(moveDirection * Time.deltaTime);
grounded = (flags & CollisionFlags.Below) != 0;
//check if we're moving backwards
if(Input.GetAxis("Vertical") < 0){
bmove = true;
}
else{
bmove = false;
}
//check if we're swimming
if(isSwimming == true){
swimSpeed = runSpeed/2;
//reduce speed when moving backwards
if(bmove == true){
if(bSpeed > 0){
bSpeed = bSpeed;
}
else{
bSpeed = swimSpeed;
swimSpeed = bSpeed * 0.6;
}
}
else{
if(bSpeed > 0){
swimSpeed = bSpeed;
bSpeed = 0.0;
}
}
moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
if(Input.GetMouseButton(1) && Input.GetAxis("Vertical") && Input.GetAxis("Horizontal")) {
moveDirection *= .7;
}
animationspeed = runSpeed/4;
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= swimSpeed;
moveStatus = "swim_idle";
if(moveDirection != Vector3.zero) {
moveStatus = "swimming";
//invoke swim animation here
}
else {
//swim idle animation
}
// Jump (or rather dive upwards)!
if(Input.GetButton("Jump"))
{
animation.CrossFade("jump");
moveDirection.y = swimSpeed*1.6;
}
// Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
if(Input.GetMouseButton(1)) {
transform.rotation = Quaternion.Euler(Camera.main.transform.eulerAngles.x,Camera.main.transform.eulerAngles.y,0);
}
else {
transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
}
//simple strafing
//now let's do the quick check if we're walking or running
//walking goes here
//left strafe button is pressed -> strafe to the left
if (Input.GetButton("Strafel")){
strafemod = new Vector3(-1, 0, 0);
strafemod = transform.TransformDirection(strafemod);
strafemod = swimSpeed * strafemod;
controller.Move (strafemod * Time.deltaTime);
}
//right strafe button is pressed -> strafe to the right
if (Input.GetButton("Strafer")){
strafemod = new Vector3(1, 0, 0);
strafemod = transform.TransformDirection(strafemod);
strafemod = swimSpeed * strafemod;
controller.Move (strafemod * Time.deltaTime);
}
}
else{
//check if we're moving
if(Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0 || Input.GetButton("StrafeL") || Input.GetButton("StrafeR")){
if(isWalking == true){
curSpeed = walkSpeed;
}
else{
curSpeed = runSpeed;
}
}
else{
curSpeed = 0.0;
//since the backward slowing can have some permanent effects to our runSpeed and walkSpeed (i.e. the speed will stick to 60%) here's some failsave code making use of the run/walk Speedsave variables
if(runSpeed < runSpeedsave){
runSpeed = runSpeedsave;
}
if(walkSpeed < walkSpeedsave){
walkSpeed = walkSpeedsave;
}
}
//reduce speed when moving backwards
if(isWalking == true){
if(bmove == true){
if(bSpeed > 0){
bSpeed = bSpeed;
}
else{
bSpeed = walkSpeed;
walkSpeed = bSpeed * 0.6;
}
}
else{
if(bSpeed > 0){
walkSpeed = bSpeed;
bSpeed = 0.0;
}
}
}
else{
if(bmove == true){
if(bSpeed > 0){
bSpeed = bSpeed;
}
else{
bSpeed = runSpeed;
runSpeed = bSpeed * 0.6;
}
}
else{
if(bSpeed > 0){
runSpeed = bSpeed;
bSpeed = 0.0;
}
}
}
//check if we're moving - if we're moving track distance and save to ddistance
if(curSpeed > 0){
ddistance = ddistance + (curSpeed * Time.deltaTime);
}
//
// Only allow movement and jumps while ----------------- GROUNDED -------------
if(grounded) {
moveDirection = new Vector3((Input.GetMouseButton(1) ? Input.GetAxis("Horizontal") : 0),0,Input.GetAxis("Vertical"));
if(Input.GetMouseButton(1) && Input.GetAxis("Vertical") && Input.GetAxis("Horizontal")) {
moveDirection *= .7;
}
animationspeed = runSpeed/4;
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= isWalking ? walkSpeed : runSpeed;
moveStatus = "idle";
if(moveDirection != Vector3.zero) {
moveStatus = isWalking ? "walking" : "running";
if (isWalking){
animation.CrossFade("walk");
} else {
animation.CrossFade("run");
}
} else {
animation.CrossFade("idle");
}
// Jump!
if(Input.GetButton("Jump"))
{
animation.CrossFade("jump");
moveDirection.y = jumpSpeed;
}
}
// END "IS GROUNDED"
// Hvis man holder begge museknapper inde.
if (Input.GetMouseButton(0) && Input.GetMouseButton(1))
{
moveDirection != Vector3.zero;
animation.CrossFade("run");
}
if(Input.GetButton("Spell1")){
animation.CrossFade("punch");
var magic = Instantiate(spell1, GameObject.Find("Bip001 R Hand").transform.position,
Quaternion.identity);
//WaitForSeconds(0.5){
magic.rigidbody.AddForce(transform.forward * 1500);
}
// Allow turning at anytime. Keep the character facing in the same direction as the Camera if the right mouse button is down.
if(Input.GetMouseButton(1)) {
transform.rotation = Quaternion.Euler(0,Camera.main.transform.eulerAngles.y,0);
}
else {
transform.Rotate(0,Input.GetAxis("Horizontal") * rotateSpeed * Time.deltaTime, 0);
}
// Toggle walking/running with the walk/run key
if(Input.GetButtonDown("Walk"))
isWalking = !isWalking;
//Apply gravity
moveDirection.y -= gravity * Time.deltaTime;
//Move controller
//var controller:CharacterController = GetComponent(CharacterController);
//var flags = controller.Move(moveDirection * Time.deltaTime);
grounded = (flags & CollisionFlags.Below) != 0;
//simple strafing
//now let's do the quick check if we're walking or running
//walking goes here
if(isWalking == true){
//left strafe button is pressed -> strafe to the left
if (Input.GetButton("StrafeL")){
strafemod = new Vector3(-1, 0, 0);
strafemod = transform.TransformDirection(strafemod);
strafemod = walkSpeed * strafemod;
controller.Move (strafemod * Time.deltaTime);
}
//right strafe button is pressed -> strafe to the right
if (Input.GetButton("StrafeR")){
strafemod = new Vector3(1, 0, 0);
strafemod = transform.TransformDirection(strafemod);
strafemod = walkSpeed * strafemod;
controller.Move (strafemod * Time.deltaTime);
}
}
//running goes here
else{
//left strafe button is pressed -> strafe to the left
if (Input.GetButton("StrafeL")){
strafemod = new Vector3(-1, 0, 0);
strafemod = transform.TransformDirection(strafemod);
strafemod = runSpeed * strafemod;
controller.Move (strafemod * Time.deltaTime);
}
//left strafe button is pressed -> strafe to the right
if (Input.GetButton("StrafeR")){
strafemod = new Vector3(1, 0, 0);
strafemod = transform.TransformDirection(strafemod);
strafemod = runSpeed * strafemod;
controller.Move (strafemod * Time.deltaTime);
}
}
}
};
static function ClampAngle (angle : float, min : float, max : float) {
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp (angle, min, max);
}
// -------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------- END UPDATE --------------------------------
// -------------------------------------------------------------------------------------------------------------
@script RequireComponent(CharacterController)
HOLY WALL OF TEXT BAT$$anonymous$$AN!
Anyway to cut this down and get abstract, your not talking about a difficult system, 600ish lines of code for a viewer may be a HUGE turn off when it comes to help.
I didn't read the script but if you want a cooldown on something you can go with:
public var cooldown : float = 5;
private var lastSpellTime : float = 0;
function CastSpell(){
//anything your spell does including playing animation
lastSpellTime = Time.time;
}
//Inside Update:
if( Time.time >= lastSpellTime + cooldown && *regular conditions for casting spell*){
CastSpell();
}
It works! - Is there any chance I can, do so it's possible to cast a spell and run/walk at the same time? Because it's only working sometimes, and is a bit unstable.
Answer by AndrewGrayGames · Feb 05, 2013 at 03:29 PM
First: That's a ton of code!
But, let's break it down a bit more easily. You need A) a cooldown system, and B) an animation. Given that I typically don't code animations, I can't answer B easily at this time. That being said, A is pretty easy.
The algorithm is pretty much this: when Spell X is used, it cannot be used until Y seconds after the time it was cast. We can simplify this by saying, 'the next time X can be used is at Y, which is at (cast time) + (cooldown seconds).'
How does this translate to C# code? Here's a simple class.
using System;
[Serializable]
public class Cooldown
{
#region Variables
public float CooldownTime = 1.5;
private float _nextUse = 0.0f;
public bool IsCooldownDone
{
get
{
return Time.time >= _nextUse;
}
}
#endregion Variables
#region Methods
public void TriggerCooldown()
{
_nextUse = Time.time + CooldownTime;
}
#endregion Methods
}
How would your skill call that in C#? Well, firstly, to enforce a GCD (Global Cooldown), all skills would inherit from a base skill:
[Serializable]
public class SkillBase
{
#region Variables
public Cooldown Cooldown = new Cooldown { CooldownTime = 2.0f };
public bool RespectsGCD = true;
// SNIP: Other skill variables
#endregion Variables
#region Methods
public virtual Use()
{
Cooldown.TriggerCooldown();
}
// SNIP: Various other things like methods.
#endregion Methods
}
...By default, your abilities have a 2sec cooldown with this setup. In your GUI, you would simply, on click of an ability that respects the GCD, go through each of the entity's abilties.
Abilities that are one-offs (e.g. defensive cooldowns) would A) not respect the GCD, and B) have a different cooldown duration.
I hope all of that helps the question that I can answer!
Your answer
Follow this Question
Related Questions
How can I tell Unity to wait to do something until after and animation has finished playing? 0 Answers
How can I tell Unity to wait to do something until after and animation has finished playing? 1 Answer
Why isn't my animation being played? 0 Answers
Changing number of frames in uvAnimationTileX 0 Answers
Wait Random time then play animation 2 Answers