角色控制腳本Character.cs,爲角色添加角色控制器Character controller。
<span style="font-size:14px;">using UnityEngine;
using System.Collections;
public class Character : MonoBehaviour {
float attackInterval = 1.5f;
float timer = 0;
public float speed = 5.0F;
public float jumpSpeed = 10.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
private Animator anim;
private CharacterController controller;
public Transform cameraTarget;
public GameObject effect1;
public GameObject effect2;
public GameObject effect3;
public GameObject AttackObj;
float Rot_y;
Health heroHealth;
Enemy enemy;
private bool isRun = false;
private bool isAttack = false;
private bool isDeath = false;
void Start () {
heroHealth = GetComponent<Health> ();
anim = GetComponent<Animator> ();
controller = GetComponent<CharacterController> ();
}
// Update is called once per frame
void Update () {
if (heroHealth.currentheroHelth > 0) {
if (!isAttack) {
Move ();
}else
Attack ();
} else if(!isDeath){
anim.SetTrigger ("Death");
isDeath = true;
}
}
void OnTriggerEnter(Collider col){
if (col.gameObject.tag == "Monster") {
isAttack = true;
anim.SetBool ("isAttack", true);
AttackObj = col.gameObject;
enemy = AttackObj.GetComponent<Enemy> ();
}
}
void OnTriggerExit(Collider col){
if (col.gameObject.tag == "Monster") {
isAttack = false;
anim.SetBool("isAttack",false);
AttackObj = null;
}
}
void Move(){
if (Input.GetKeyDown (KeyCode.LeftShift)) {
if (!isRun) {
isRun = true;
anim.SetBool ("isRun", true);
} else {
isRun = false;
anim.SetBool ("isRun", false);
}
}
if (controller.isGrounded) {
if (Input.GetButtonDown ("Jump")) {
moveDirection.y = jumpSpeed;
}
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move( moveDirection * Time.deltaTime);
if (Input.GetKey (KeyCode.A) || Input.GetKey (KeyCode.D) || Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.S)) {
anim.SetInteger ("ActionID", 1);
if (Input.GetKeyDown (KeyCode.W)) {
Rot_y = cameraTarget.rotation.eulerAngles.y + 180;
} else if (Input.GetKeyDown (KeyCode.S)) {
Rot_y = cameraTarget.rotation.eulerAngles.y;
} else if (Input.GetKeyDown (KeyCode.A)) {
Rot_y = cameraTarget.rotation.eulerAngles.y + 90;
} else if (Input.GetKeyDown (KeyCode.D)) {
Rot_y = cameraTarget.rotation.eulerAngles.y - 90;
}
if (!isRun) {
controller.Move (transform.forward * -speed * Time.deltaTime);
} else
controller.Move (transform.forward * -speed * 2 * Time.deltaTime);
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.Euler (0, Rot_y, 0), Time.deltaTime * 6);
} else if (Input.GetMouseButton (1)) {
anim.SetInteger ("ActionID", 1);
} else {
anim.SetInteger ("ActionID", 0);
anim.SetInteger ("AttackID", 0);
}
}
void Attack(){
timer += Time.deltaTime;
if (Input.GetKeyDown (KeyCode.LeftShift)) {
if (!isRun) {
isRun = true;
anim.SetBool ("isRun", true);
} else {
isRun = false;
anim.SetBool ("isRun", false);
}
}
if (Input.GetKey (KeyCode.A) || Input.GetKey (KeyCode.D) || Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.S)) {
anim.SetInteger ("AttackID", 4);
if (Input.GetKeyDown (KeyCode.W)) {
Rot_y = cameraTarget.rotation.eulerAngles.y + 180;
} else if (Input.GetKeyDown (KeyCode.S)) {
Rot_y = cameraTarget.rotation.eulerAngles.y;
} else if (Input.GetKeyDown (KeyCode.A)) {
Rot_y = cameraTarget.rotation.eulerAngles.y + 90;
} else if (Input.GetKeyDown (KeyCode.D)) {
Rot_y = cameraTarget.rotation.eulerAngles.y - 90;
}
if (!isRun) {
controller.Move (transform.forward * -speed * Time.deltaTime);
} else
controller.Move (transform.forward * -speed * 2 * Time.deltaTime);
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.Euler (0, Rot_y, 0), Time.deltaTime * 6);
} else if (Input.GetKeyDown (KeyCode.J)) {
transform.LookAt (AttackObj.transform.position);
transform.eulerAngles += new Vector3 (0, 180, 0);
if (timer >= attackInterval && enemy.currentEnemyHp > 0) {
anim.SetInteger ("AttackID", 1);
WaitAttackMonster (effect1);
timer = 0;
}
} else if (Input.GetKeyDown (KeyCode.K)) {
transform.LookAt (AttackObj.transform.position);
transform.eulerAngles += new Vector3 (0, 180, 0);
if (timer >= attackInterval && enemy.currentEnemyHp > 0) {
anim.SetInteger ("AttackID", 2);
WaitAttackMonster (effect2);
timer = 0;
}
} else if (Input.GetKeyDown (KeyCode.L)) {
transform.LookAt (AttackObj.transform.position);
transform.eulerAngles += new Vector3 (0, 180, 0);
if (timer >= attackInterval && enemy.currentEnemyHp > 0) {
anim.SetInteger ("AttackID", 3);
WaitAttackMonster (effect3);
timer = 0;
}
}else if (Input.GetMouseButton (1)) {
anim.SetInteger ("AttackID", 4);
} else {
anim.SetInteger ("AttackID", 0);
anim.SetInteger ("ActionID", 0);
}
}
void WaitAttackMonster(GameObject effect){
enemy.currentEnemyHp -= heroHealth.attack;
GameObject proObj = (GameObject)Instantiate (effect, AttackObj.transform.position, Quaternion.identity);
}
}</span>
角色屬性腳本Health.cs<span style="font-size:14px;">using UnityEngine;
using System.Collections;
public class Health : MonoBehaviour {
public int attack = 20;
public int heroHealth = 100;
public int currentheroHelth;
public bool isDamage = false;
UIManager uiManager;
void Awake(){
currentheroHelth = heroHealth;
uiManager = GameObject.FindGameObjectWithTag ("UIManager").GetComponent<UIManager> ();
}
public void TakeDamage(int damage){
isDamage = true;
currentheroHelth -= damage;
uiManager.updateHealthBar (currentheroHelth);
}
}</span>
敵人AI戰鬥腳本 Enemy.cs,爲敵人添加標籤(tag)“Monster”,添加尋路組件NavMeshAgent,把環境靜態變量變成True進行路徑(Navigation)渲染Bake<span style="font-size:14px;">using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Enemy : MonoBehaviour {
public Sprite Head;
public int EnemyHp = 200;
public int currentEnemyHp;
GameObject hero;
NavMeshAgent agent;
Animator anim;
CharacterController controller;
public int attack = 20;
public float attackInterval = 2f;
float timer = 0;
Health heroHealth;
float dis;
float times = 10.0f;
int Action;
bool heroInRange;
bool isDeath = false;
void Awake(){
currentEnemyHp = EnemyHp;
hero = GameObject.FindGameObjectWithTag ("Player");
heroHealth = hero.GetComponent<Health> ();
agent = GetComponent<NavMeshAgent> ();
anim = GetComponent<Animator> ();
controller = GetComponent<CharacterController> ();
}
void Update(){
dis = Vector3.Distance (this.transform.position, hero.transform.position);
if (currentEnemyHp > 0) {
Activity ();
} else if (!isDeath) {
anim.SetTrigger ("Death");
isDeath = true;
}
}
void Activity(){
if (dis > 15) {
anim.SetBool ("isRun", false);
anim.SetBool ("isAttack", false);
times -= Time.deltaTime;
if (times < 0) {
Action = Random.Range (0, 5);
times = 10.0f;
}
switch (Action) {
case 0:
anim.SetBool ("isWalk", false);
transform.Rotate (0, 8 * Time.deltaTime, 0);
break;
case 1:
anim.SetBool ("isWalk", false);
transform.Rotate (0, -8 * Time.deltaTime, 0);
break;
case 2:
anim.SetBool ("isWalk", true);
controller.Move (transform.forward * -3 * Time.deltaTime);
break;
default:
anim.SetBool ("isWalk", false);
break;
}
} else if (dis > 7 && dis <= 15) {
anim.SetBool ("isWalk", false);
anim.SetBool ("isAttack", false);
anim.SetBool ("isRun", true);
transform.LookAt (hero.transform.position);
transform.eulerAngles += new Vector3 (0, 180, 0);
agent.SetDestination (hero.transform.position);
} else {
anim.SetBool ("isWalk", false);
anim.SetBool ("isRun", false);
anim.SetBool ("isAttack", true);
transform.LookAt (hero.transform.position);
transform.eulerAngles += new Vector3 (0, 180, 0);
timer += Time.deltaTime;
if (timer >= attackInterval) {
Attack ();
timer = 0;
}
}
}
void Attack(){
int ActionAttack = Random.Range (1, 5);
if (heroHealth.currentheroHelth > 0) {
switch (ActionAttack) {
case 1:
anim.SetInteger ("AttackID", 1);
break;
case 2:
anim.SetInteger ("AttackID", 2);
break;
case 3:
anim.SetInteger ("AttackID", 3);
break;
default:
anim.SetInteger ("AttackID", 4);
break;
}
if(heroInRange)
heroHealth.TakeDamage (attack);
}else
anim.SetInteger ("AttackID", 0);
}
void OnTriggerEnter(Collider col){
if (col.gameObject == hero) {
heroInRange = true;
}
}
void OnTriggerExit(Collider col){
if (col.gameObject == hero) {
heroInRange = false;
}
}
}</span>
UI管理腳本UIManager.cs
<span style="font-size:14px;">using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class UIManager : MonoBehaviour {
Health heroHealth;
Character character;
public Slider HealthBar;
public Slider EnemyHpBar;
public Image Head;
public Image flashScreen;
public float flashSpeed = 0.5f;
public Color flashColor = new Color (1f, 0f, 0f, 0.1f);
void Awake(){
heroHealth = GameObject.FindGameObjectWithTag ("Player").GetComponent<Health> ();
character = GameObject.FindGameObjectWithTag ("Player").GetComponent<Character> ();
}
public void updateHealthBar(int value){
HealthBar.value = (float)value / heroHealth.heroHealth;
}
void Update(){
if (!character.AttackObj) {
EnemyHpBar.gameObject.SetActive (false);
Head.gameObject.SetActive (false);
} else {
Enemy enemy = character.AttackObj.GetComponent<Enemy> ();
EnemyHpBar.gameObject.SetActive (true);
Head.gameObject.SetActive (true);
EnemyHpBar.value = (float)enemy.currentEnemyHp / enemy.EnemyHp;
Head.sprite = enemy.Head;
}
if (heroHealth.isDamage) {
flashScreen.color = flashColor;
} else {
flashScreen.color = Color.Lerp (flashScreen.color, Color.clear, flashSpeed * Time.deltaTime);
}
heroHealth.isDamage = false;
}
}</span>
最後幾張運行效果圖