UNITY RPG COMBAT SYSTEM TUTORIAL WITH STATE MACHINE JAVASCRIPT FULL CODE DOWNLOAD EXAMPLES

UNITY RPG COMBAT SYSTEM TUTORIAL WITH STATE MACHINE JAVASCRIPT FULL CODE DOWNLOAD EXAMPLES

Share

UNITY RPG COMBAT SYSTEM TUTORIAL WITH STATE MACHINE JAVASCRIPT FULL CODE DOWNLOAD EXAMPLES

UNITY RPG COMBAT SYSTEM TUTORIAL WITH STATE MACHINE JAVASCRIPT FULL CODE DOWNLOAD EXAMPLES

PlayerController.js

[javascript]
/* WASD keyboard input player movement control with jump
and mouse rotation – Unity javascript Gameobject.net*/

#pragma strict
var charController:CharacterController ;
/* Create a variable of type CharacterController to store
our component and call it in the script */
var walkSpeed : float = 1 ;
var runSpeed : float = 1.8 ;
var rotationSpeed : float = 250 ;
var jumpForceDefault : float = 2 ;
var cooldown : float = 5 ;

private var jumpForce : float;
private var gravityPull : float = 1;
/* Jump action related costants */

private var isRunning : boolean ;
private var isWalking : boolean ;
private var isStrafing : boolean ;
private var isJumping : boolean ;
// CHANGE isAttacking to PUBLIC to access it from
// CombatBox script
public var isAttacking : boolean ;
private var isIdle : boolean ;
/* Create boolean status variables to identify animation
status, e.g. what am i doing right now? */

function Start (){
var cc : CharacterController;
cc = gameObject.AddComponent(“CharacterController”);
/* Adds a Character Controller component to gameobject */

charController = GetComponent(CharacterController);
/* Assigns it in the charController variable to use it */

// Set all animations to loop
animation.wrapMode = WrapMode.Loop;
// except shooting
animation[“attack”].wrapMode = WrapMode.Once;

// Put idle and walk into lower layers (The default layer is always 0)
// This will do two things
// – Since shoot and idle/walk are in different layers they will not affect
// each other’s playback when calling CrossFade.
// – Since shoot is in a higher layer, the animation will replace idle/walk
// animations when faded in.
animation[“attack”].layer = 1;

// Stop animations that are already playing
//(In case user forgot to disable play automatically)
animation.Stop();

}

function Update(){

charController.Move(transform.up * Time.deltaTime * -gravityPull * 1);

/* Gravity */

if(Input.GetAxis(“Vertical”) > 0){
/* If the Vertical input axis is positive (by default by
pressing W or up arrow) */
if(Input.GetButton(“Fire3”)){
isRunning = true ;
animation.CrossFade(“run”);
/* While Run button is pressed play run animation, with
Crossfade try to blend nicely different animations )*/
charController.Move(transform.forward*Time.deltaTime*runSpeed) ;
/* While Run button is pressed move faster !) */
/* Use the Move function, Time.deltatime makes things go
equally fast on different hardware configurations,
by moving in the forward direction with walkspeed */
isRunning = true ;
/* Set the isRunning flag as true since i am running */
Debug.Log(“isRunning value is” + ” ” + isRunning);
/* Tell me what i am doing now */
}
else{
isWalking = true ;
/* Else if i am moving forward and not running i walk */
animation[“walk”].speed = 1;
animation.CrossFade(“walk”);
/* While walk button is pressed play walk animation ! */
charController.Move(transform.forward*Time.deltaTime*walkSpeed) ;
//Debug.Log(“isWalking value is” + ” ” + isWalking);
/* Tell me what i am doing now */
}
}
else if(Input.GetAxis(“Vertical”) < 0){ isWalking = true ; /* Do the same for the back direction, no back run! */ animation["walk"].speed = 0.5; /* revert walk animation playback */ animation.CrossFade("walk"); charController.Move(transform.forward*Time.deltaTime*-walkSpeed/2) ; /* Move function but in the opposite to forward direction by using a negative (-) vector */ //Debug.Log("isWalking value is" + " " + isWalking); /* Tell me what i am doing now */ } else{ isWalking = false ; isRunning = false ; /* if not running or walking set these states as false */ } if(Input.GetButtonDown("Jump") && !isJumping){ jumpForce = jumpForceDefault ; isJumping = true ; animation.Play("jump_pose") ; /* Capture Jump input and prevent double air jump with && !isJumping, makes these lines working only while not already in a Jump. */ } if(isJumping){ charController.Move(transform.up * Time.deltaTime * jumpForce); jumpForce -= gravityPull ; Debug.Log("isJumping value is" + " " + isJumping); /* If isJumping is true (i am in Jump state), move the character up with jumpForce intensty, then gravityPull kicks in and will take you on the ground. */ if(charController.isGrounded){ isJumping = false ; /* Check if the character is touching the ground with Unity default isGrounded function, if its grounded end the Jumping action by setting isJumping false */ } } if(!isWalking && !isRunning && !isJumping){ animation.CrossFade("idle"); /* If i am not doing any action , play the idle anim */ } if(Input.GetAxis("Horizontal") > 0){
charController.transform.Rotate(Vector3.up * Time.deltaTime * 20 * rotationSpeed, Space.World);
}
if(Input.GetAxis(“Horizontal”) < 0){ charController.transform.Rotate(Vector3.up * Time.deltaTime * 20 * -rotationSpeed); } /* rotate the character with left and right arrows */ charController.transform.rotation.y += Input.GetAxis("Mouse X") * Time.deltaTime * rotationSpeed ; /* rotate the character with the mouse */ /* Play attack animation calling slash function and make sure it isn calling more than once */ if(Input.GetButtonDown("Fire1") && !isAttacking){ slash() ; } /* If you wish to add STRAFE command just replicate the code for the forward and back direction , i am not doing this in this character controller tutorial because the Constructor model is not provided with the strafe animation. */ } //Modify the attack Slash function to change the isAttacking //state variable accordingly to the timing of the //attack animation function slash(){ isAttacking = true ; animation.CrossFade("attack"); yield WaitForSeconds (animation["attack"].length); isAttacking = false ; } [/javascript] enemyAi.js [javascript] /* enemyAi.js - Unity rpg combat system tutorial - www.Gameobject.net */ /* Author : Piffa of www.Gameobject.net */ #pragma strict /* delcaring states to pass to player gameobject */ public var isAttacking : boolean = false ; public var enemyHealthPoints : int = 10 ; // Health pool for the enemy public var enemyDamage : int = 1 ; // Damage dealt by enemy per hit private var playAnim : boolean = true ; function Update () { if (playAnim){ //check if attack animation was played WaitSeconds(); //wait random seconds for animation } //Destroy enemy if hp drops to zero and destroy it if so if(enemyHealthPoints < 0){ Destroy(gameObject); Debug.Log("Enemy is Dead !!!"); } } function WaitSeconds(){ playAnim = false; var randomWait = Random.Range(0, 6); print ("Wait" + randomWait + " seconds"); //debug yield WaitForSeconds(randomWait); //Wait a random amount of time isAttacking = true ; //set isAttacking state to true animation.Play("punch"); //play attack animation yield WaitForSeconds(animation["punch"].length) ;//wait for animation duration isAttacking = false ;//set isAttacking state to false playAnim = true ; // detect when anim is complete } //Function to call when hit by player function TakeDamage(dmg : int){ enemyHealthPoints -= dmg ; Debug.Log("Enemy suffered " + dmg +" damages"); } [/javascript] CombatSystem.js [javascript] /* CombatSystem.js - Unity rpg combat system tutorial - www.Gameobject.net */ /* Author : Piffa of www.Gameobject.net */ #pragma strict /* Declaring and inizializing private variables to define collisions states */ public var isTouching : boolean = false; // player is touching an enemy collider box public var wasTouching : boolean = false;// player was touching an enemy collider box public var isEngaged : boolean = false; // player and enemy are engaged in combat public var isHitting : boolean = false; // player is landing an hit and dealing dmg public var isHitted : boolean = false ; // enemy is landing an hit to player public var playerControllerScript : PlayerController ; //handle to access parent player gameobject private var playerIsAttacking : boolean ; //read from Playercontroller.js if player is attacking private var enemyIsAttacking : boolean ; //read from enemyAi.js if enemy is attacking private var collidingEnemy : GameObject ; // reference to enemy gameobject we are colliding with public var playerHealthPoints : int = 20 ; // player health pool private var playerDamage : int = 2 ; // amount of damage dealt by player with 1 hit function Start () { playerControllerScript = transform.parent.gameObject.GetComponent(PlayerController); //Get the PlayerController script in our parent gameobject and store in a variable } function Update () { /* player is engaged in combat if for the first time is touching the enemy's collider */ if(!wasTouching && isTouching){ isEngaged = true; }; /* player is not engaged anymore if was touching the enemy and now it's not anymore */ if(wasTouching && !isTouching){ isEngaged = false; }; /* Store in a variable if the player is attacking */ playerIsAttacking = playerControllerScript.isAttacking; /* Store in a variable if the enemy is attacking */ if(collidingEnemy){ enemyIsAttacking = collidingEnemy.GetComponent(enemyAi).isAttacking; }; Debug.Log(enemyIsAttacking); /* if player is attacking while engaged and in touch with the enemy apply damage to the enemy by calling its takedamage function via sendmessage */ if(playerIsAttacking && isEngaged && isTouching){ if(isHitting==false){ isHitting=true; collidingEnemy.SendMessage("TakeDamage",playerDamage); }else if(!transform.parent.gameObject.animation.IsPlaying("attack")){ isHitting=false; } } /* if player is attacking while engaged and in touch with the enemy apply damage to the enemy by calling its takedamage function via sendmessage */ if(enemyIsAttacking && isEngaged && isTouching){ if(isHitted==false){ isHitted=true; TakeDamage(collidingEnemy.gameObject.GetComponent(enemyAi).enemyDamage); } }else if(!enemyIsAttacking){ isHitted=false; //FIXARE PERCHE NON TORNA FALSE } } /* The above state machine logic it's needed to avoid to call the takedamage function every frame that verify the if statement thus applying more than needed. This way the function is called just once for every hit landed as it should. */ /* Check for collision with enemy and flag states appropriately */ function OnTriggerEnter(col : Collider) { if(col.gameObject.name =="demon"){ wasTouching = isTouching; isTouching = true; collidingEnemy = col.gameObject; }; } /* Check for collision with enemy and flag states appropriately */ function OnTriggerExit(col : Collider) { Debug.Log("Colliding with : " + col.gameObject.name); if(col.gameObject.name =="demon"){ wasTouching = isTouching; isTouching = false; }; } //Function to call when hit by enemy function TakeDamage(dmg : int){ playerHealthPoints -= dmg ; Debug.Log("Player suffered " + dmg +" damages"); } [/javascript]

Leave a Comment