模型与动画

May 11, 2018


低智能巡逻兵

Image text

游戏内容

跑来跑去。

躲避骷髅兵,不能被骷髅兵抓到。

当与骷髅兵有一定距离时,算作甩掉骷髅兵,加一分。

W向前跑,S向后转,AD向左向右转。

游戏架构

除了导演场记,门面,动作管理器,工厂,新增了事件管理器。

事件管理器(GameEventManager),用来管理事件。碰撞核为Publisher,场记为Subscriber

画面实现

Garen, hero~

一个Plane

根据预制,制作十个骷髅兵,五个墓碑

碰撞核

Plane中需要一个Mesh Collider

Garen需要Rigidbody和胶囊碰撞核(不需要触发)

骷髅兵需要两个碰撞核,Box Collider在Garen进入骷髅兵一定范围时触发,胶囊碰撞核来判断Garen与骷髅兵的碰撞

墓碑需要Box Collider

动画

Garen默认是站立动作,当检测到W键按下,设置Trigger,变为奔跑动作

骷髅默认是行走动作,当Box Collier与Garen碰撞时,设置Trigger,变为奔跑状态

MonsterCollider

挂载到骷髅上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 用来检测Box Collider的触发,以检测Garen是否进入骷髅追击范围内
void OnTriggerEnter(Collider c) {
	if (c.gameObject.name.Contains ("Plane"))
		return;

	if (c.gameObject.name.Contains ("Garen")) {
		gameObject.GetComponent<MonsterData> ().speed = 2f;
	}
}
// 用来检测胶囊碰撞核的触发,以检测实际碰撞
void OnCollisionEnter(Collision c) {
	if (c.gameObject.name.Contains ("Garen")) {
		GameEventManager.Instance.GameOver ();
	} else {
		var vec = gameObject.GetComponent<MonsterData> ().direction;
		gameObject.GetComponent<MonsterData> ().direction = -vec;
		}
}

CCMAct

骷髅的动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using UnityEngine;
using System.Collections;

public class CCMAct: SSAction
{
	public FirstController sceneController; 

	private Animator ani;
	// 自定义Component
	private MonsterData data;

	public static CCMAct GetSSAction()
	{  
		return ScriptableObject.CreateInstance<CCMAct>();
	}  
	// Use this for initialization  
	public override void Start()
	{
		ani = gameobject.GetComponent<Animator> ();
		data = gameobject.GetComponent<MonsterData> ();
		sceneController = (FirstController)SSDirector.Instance.currentSceneController;

	}

	public override void Update() {
		
		// 记录骷髅沿当前方向走了多久
		data.time += Time.deltaTime;
		transform.Translate (Vector3.forward*Time.deltaTime*data.speed);
		// 只是在根据骷髅跑动的速度来判断是否在追击
		if (data.speed == 2f) {
			ani.SetTrigger ("run");
		}
		this.destroy = true;
		this.callback.SSActionEvent (this);
	}
}

CCPAct

Garen的动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using UnityEngine;
using System.Collections;

public class CCPAct: SSAction
{
	public FirstController sceneController; 

	private Animator ani;

	public static CCPAct GetSSAction()
	{  
		return ScriptableObject.CreateInstance<CCPAct>();
	}  
	// Use this for initialization  
	public override void Start()
	{
		ani = gameobject.GetComponent<Animator> ();
		sceneController = (FirstController)SSDirector.Instance.currentSceneController;
        // 在判断Garen是否卡进BUG里。保证Garen在地面上
		if (transform.rotation.z > 0.000001f || transform.rotation.x > 0.000001f) {
			var r = transform.rotation;
			Quaternion q = new Quaternion ();
			q.Set(0f,r.y,0f,r.w);
			transform.rotation = q;
		}
        // 消除Garen身上力作用出来的速度
		if (transform.position.y < 1f)
			gameobject.GetComponent<Rigidbody> ().velocity = Vector3.zero;
	}

	public override void Update() {
		
		// 跑啊跑
		if (Input.GetKey (KeyCode.W)) {
			ani.SetTrigger ("run");
			transform.Translate (Vector3.forward*Time.deltaTime*5);
		}
		// 转向
		if (Input.GetKey (KeyCode.S)) {
			transform.Rotate (0,180*Time.deltaTime,0);
		}
		if (Input.GetKey (KeyCode.A)) {
			transform.Rotate (0,-90*Time.deltaTime,0);
		}
		if (Input.GetKey (KeyCode.D)) {
			transform.Rotate (0,90*Time.deltaTime,0);
		}

		this.destroy = true;
		this.callback.SSActionEvent (this);
	}
}

CCActionManager

检测到鼠标点击时,管理箭执行发射动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
	protected new void Update () {

	    // 判断游戏是否结束
		if (sceneController.over)
			return; 

        // 为Garen添加动作
		pAct = CCPAct.GetSSAction();
		this.RunAction (sceneController.player, pAct, this);

        // 为每个骷髅添加动作
		foreach (var gb in sceneController.mons) {
			int ran = Random.Range (0, 10);
			var data = gb.GetComponent<MonsterData> ();
			// 根据速度判断是否在追击
			if (data.speed == 2f) {
				// 判断Garen是否跑出骷髅的追击范围
				if ((gb.transform.position - sceneController.player.transform.position).sqrMagnitude > 50f) {
					GameEventManager.Instance.OnLostGoal ();
					gb.GetComponent<MonsterData> ().speed = 1f;
				}
				// 继续追击
				else {
					gb.GetComponent<MonsterData> ().time = 0f;
					gb.transform.LookAt (sceneController.player.transform.position);
				}

			}
			// 随机转向
			else if (ran == 1 && data.time > 10f) {
				gb.GetComponent<MonsterData> ().time = 0f;
				gb.GetComponent<MonsterData> ().direction = new Vector3 (Random.Range (-30,30), 0, Random.Range(-30,30));
				gb.transform.LookAt (gb.GetComponent<MonsterData> ().direction);
			}
				
			mAct = CCMAct.GetSSAction();
			this.RunAction (gb, mAct, this);
		}

		base.Update();  
	}

参考资料