1. 程式人生 > >Unity3d即時戰鬥之敵人AI和角色攻擊

Unity3d即時戰鬥之敵人AI和角色攻擊

角色控制指令碼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>
最後幾張執行效果圖




相關推薦

Unity3d即時戰鬥敵人AI角色攻擊

角色控制指令碼Character.cs,為角色新增角色控制器Character controller。 <span style="font-size:14px;">using UnityEngine; using System.Collections; pub

Unity3D學習筆記碰撞器觸發器

碰撞器種類: Box Collider(盒碰撞器)——立方體 Sphere Collider(球碰撞器)——球體 Capsule Collider(膠囊碰撞器)——膠囊體 Mesh Collider(網格碰撞器)——從物體的網格建立一個碰撞器,不能與其他網格碰撞器相碰撞

Unity3D】學習筆記(第1記) 敵人AISeek(靠近)

using UnityEngine; using System.Collections; public class enemyController : MonoBehaviour { publi

網際網路大腦架構分析阿里巴巴:商業AI雲端計算AI是其重點領域

【資料猿導讀】 阿里依託在商業,工業生態的服務和資料優勢,建設包括阿里人工智慧實驗室,阿里巴巴

oracle逐步學習總結許可權角色(基礎六)

原創作品,轉自請註明出處:https://www.cnblogs.com/sunshine5683/p/10236129.html 繼續上節的索引,這次主要總結oracle資料庫的許可權問題!(在總結的過程中,後續會不斷完善) 一、索引 1、單列索引:基於單個列建立的索引 建立單列索引:create

Unity3D入門基礎遊戲物件 (GameObject) 元件 (Component) 的關係

原文出處:http://edu.china.unity3d.com/learning_document/getData?file=/Manual/TheGameObject-ComponentRelationship.html 我們在使用Unity的時候,會經常建立一個遊戲

Deeplearning.ai吳恩達筆記神經網路深度學習1

Introduction to Deep Learning What is a neural neural network? 當對於房價進行預測時,因為我們知道房子價格是不可能會有負數的,因此我們讓面積小於某個值時,價格始終為零。 其實對於以上這麼一個預測的模型就可以看

Deeplearning.ai吳恩達筆記神經網路深度學習3

Shallow Neural Network Neural Networks Overview 同樣,反向傳播過程也分成兩層。第一層是輸出層到隱藏層,第二層是隱藏層到輸入層。其細節部分我們之後再來討論。 Neural Network Representation

unity官方demo學習Stealth(二十四)敵人AI

1,新增指令碼檔案DoneEnemyAI using UnityEngine; using System.Collections; public class DoneEnemyAI : MonoBehaviour { public float patrolSpeed

Unity3D動畫系統Timeline

1. 普通動畫    由Animation、Animator Controller以及Animator三部分構成,通過選中游戲物體點選Window->Animation(Ctrl+6)建立,或逐步建立Animation和Animator,Animator建立在物體身上,

Unity3D入門——GUIButtonRepeatButton控制元件

using UnityEngine; using System.Collections; public class Button : MonoBehaviour { public Texture img;//公有變數圖片/ private Texture img0; private string in

unity3d 分包與上google play 環境搭建各種賬號註冊

環境:我們遊戲是一款重度ARPG網路遊戲,unity打包大於200M, 現在需要上google play (需求是<=50M,  海外需求方必須的要求),後面這個會做個系列,以幫助那些有這個需求的同學。(中國大陸開發者的坎坷~~) 1: GOOGLE 開發者賬號申請 

【轉】【UNITY3D 遊戲開發五】Google-protobuf與FlatBuffers資料的序列化反序列化

★protobuf有啥缺陷?前幾天剛剛在“光環效應 ”的帖子裡強調了“要同時評估優點和缺點”。所以俺最後再來批判一下這玩意兒的缺點。◇應用 不夠廣由於protobuf剛公佈沒多久,相比XML而言,protobuf還屬於初出茅廬。因此,在知名度、應用廣度等方面都遠不如XML。由於這個原因,假如你設計的系統需要提

[Unity3D]Unity3D遊戲開發仿仙劍奇俠傳角色死亡效果實現

         感謝對我的支援,在上一篇文章《 [Unity3D]Unity3D遊戲開發之仿仙劍奇俠傳角色控制效果》中,我們通過自定義指令碼實現了在RPG遊戲中的角色控制器,當然這個角色器目前還不完善,在碰撞以及控制等方面還存在某些問題和不足,對於這些問題,我會在後面的

Sql Server 2008 R2資料庫登入名、使用者、架構、許可權角色

原文地址http://www.shaoqun.com/a/106188.aspx 這幾天先是研究了一下有關資料庫的安全性、許可權等方面的東西,那就是先說一下資料庫安全性和許可權的問題,首先是對資料庫的登入名、使用者和架構做一個簡單的介紹。登入名大家都知道就是登入資料庫時

UNITY3D 遊戲開發五】Google-protobuf與FlatBuffers資料的序列化反序列化

 關於Protobuf 通過本文的轉載和分享的相關連結,足夠了解使用了,所以這裡不贅述了。但是這裡Himi順便提一下“FlatBuffers” ,它是 Protocol Buffers升級版,其主要區別在於FlatBuffers在訪問資料前不需要解析/拆包這一步。

Unity3D C#語法==!=運算子過載

前言 在編碼中,為了提高程式碼的可讀性,我們常常會去過載運算子以封裝一些運算,良好的運算子過載,能夠極大的提高程式碼的可讀性。本文會講==以及!=運算子過載。 過載函式 在C#中,過載的時候需要使用operator關鍵詞來宣告: public s

移動web開發像素DPR

javascript element 英語單詞 計算機 web開發 定義  像素,又稱畫素,是圖像顯示的基本單位,譯自英文“pixel”,pix是英語單詞picture的常用簡寫,加上英語單詞“元素”element,就得到pixel,故“像素”表示“圖像元素”之意,有時亦被稱為pel(pi

C語言運算符條件結構

比較運算 第三名 user 石頭 年齡 pan 註意 break -1 表達式:是有操作數和運算符組成的。 操作數:常量、變量、子表達式 X=(x+2)*(y-2); 運算符: 賦值運算符:= 。其作用是做賦值運算,將等號後邊的值賦值給等號前邊的。 復合賦值運算符: +=

Unity3D中tolua的“安裝部署使用“教程

替換 部署 ref 比對 text asset gin 系統 .com 棄坑Cocos2d-x,轉戰Unity3D 考慮到項目一定會使用熱更,花了不少時間比對了lua的支持方案,最後定為tolua,原因不解釋。 俗話說,萬事開頭難,中間難,最後難……我反正是沒有找到如何安裝