Unity3DGame学习笔记(5):飞碟修改

实验要求:


由于我的原版作业实现运动是用物理运动,所以这次我需要实现运动学运动。

修改说明:

1.增添了接口IActionManager,用于统一调用物理运动和运动学运动。
2.对于物理运动,我增添了PhysicsActionManager来实现物理运动的细节。
3.对于运动学运动,根据课程ActionManager的框架,增添了CCActionManager,SSAction和CCAction来实现运动学运动的细节。

UML图:


完整代码:

1.UserInterface:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UserInterface : MonoBehaviour {
	GameObject cam;
	Camera ca;
	float time = 0;

	public ParticleSystem explosion;
	public Text scoreText;
	public Text roundText;
	//public Text DiskNumText;
	public Text TotalScore;
	public Text TimeText;

	SceneController Controller;

	// Use this for initialization
	void Awake () {
		cam = GameObject.Find ("Camera");
		ca = cam.GetComponent<Camera> ();
		//explosion = Instantiate (Resources.Load ("Prefabs/explosion")) as ParticleSystem;
		Controller = SceneController.getControllerInstance ();
		Controller.nextRound ();
	}
	
	// Update is called once per frame
	void Update () {
		if (Input.GetMouseButtonDown (0)) {
			Vector3 mp = Input.mousePosition;
			Ray ray = ca.ScreenPointToRay (Input.mousePosition);

			RaycastHit hit;
			if (Physics.Raycast (ray, out hit, Mathf.Infinity) && hit.collider.gameObject.tag == "Disk") {
				print ("I hit " + hit.transform.gameObject.name);
				hit.collider.gameObject.SetActive (false);
				PlayExplosion (hit.collider.gameObject);
				Controller.getRecorder ().getScore (hit.collider.gameObject);
			}
		}
		if (Input.GetKeyDown("space")) {
			Debug.Log ("Space Down");
			if (time <= 0) {
				time = 3;
				if (Controller.getRound () == 2) {
					Controller.emitDisk ();
				}
				Controller.emitDisk ();
			}
		}
		if (time > 0) {
			time -= Time.deltaTime;
			TimeText.text = "Next Disk Time : " + (int)(time + 0.5);
		} else {
			TimeText.text = "Disk Ready!";
		}

		scoreText.text = "TempScore : " + Controller.getRecorder ().returnScore ();
		roundText.text = "Round : " + Controller.getRound ();
		TotalScore.text = "TotalScore : " + Controller.getRecorder ().returnTScore ();
	}

	void PlayExplosion(GameObject t) {
		Debug.Log (explosion);
		explosion.transform.position = t.transform.position;
		explosion.GetComponent<Renderer>().material.color = t.GetComponent<Renderer>().material.color;
		explosion.Play ();
	}
}
2.SceneController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SceneController : System.Object {
	private static SceneController Controller_instance;
	private ScoreRecorder Recorder_instance;
	private DiskFactory Factory_instance;
	private int RoundNow = 0;

	private IActionManager IAction;
	private CCActionManager ccAction; //注册一个CCAction
	private PhysicsActionManager physicsAction; //注册一个PhysicsAction
	private int turn = 1; //用来交替使用物理和运动学动作,1位物理,-1为运动学

	Vector3 emitPos = new Vector3(-1.5f, 0.5f, 0.5f);
	Vector3 emitDir = new Vector3(10f, 50.0f, 67f);
	float emitSpeed = 0.5f;
	Color color;

	public static SceneController getControllerInstance () {
		if (Controller_instance == null) {
			Controller_instance = new SceneController();
		}
		return Controller_instance;
	}

	public ScoreRecorder getRecorder() {
		return Recorder_instance;
	}

	public void setRecorder(ScoreRecorder R) {
		Recorder_instance = R;
	}

	public DiskFactory getFactory() {
		return Factory_instance;
	}

	public void setFactory(DiskFactory F) {
		Factory_instance = F;
	}

	public void setCCActionManager(CCActionManager ca) {
		ccAction = ca;
	}

	public void emitDisk() {
		GameObject temp = Factory_instance.getDisk();
		if (temp == null) {
			Debug.Log ("No disk, Please wait!");
			return;
		}
		temp.transform.position = emitPos;
		if (turn == 1) {
			physicsAction = new PhysicsActionManager ();
			physicsAction.setPhysicsAction (temp, emitDir, emitSpeed);
			turn = -turn;
			IAction = physicsAction;
			//物理运动
		} else if (turn == -1) {
			ccAction.setCCAction (temp, emitSpeed);
			turn = -turn;
			IAction = ccAction;
			//运动学运动
		}
		IAction.playDisk ();
	}

	public void nextRound() {
		Factory_instance.DisableDisk ();
		if (RoundNow == 1) {
			RoundNow = 2;
		} else if (RoundNow == 2) {
			RoundNow = 1;
		} else {
			RoundNow = 1;
		}
		Round (RoundNow);
	}

	public void Round(int R) {
		Debug.Log ("Round = " + R);
		switch(R) {
		case 1:
			emitPos = new Vector3 (-1.5f, 0.5f, 0.5f);
			emitSpeed = 0.5f;
			color = Color.green;
			Factory_instance.setDisk (color, emitSpeed, 1f, 1);
			break;
		case 2:
			emitPos = new Vector3 (1.5f, 0.5f, 0.5f);
			emitSpeed = 0.7f;
			color = Color.red;
			Factory_instance.setDisk (color, emitSpeed, 0.8f, 2);
			break;
		}
	}

	public int getRound() {
		return RoundNow;
	}
}
3.IActionManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IActionManager {
	void playDisk();
}
4.CCActionManager:
这个代码结合了课程的CCActionManager和SSActionManager。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CCActionManager : MonoBehaviour ,IActionManager {
	private GameObject temp;
	private float speed;
	private Vector3 target;
	private CCAction ccAction;

	private Dictionary <int, SSAction> actions = new Dictionary<int, SSAction> ();
	private List<SSAction> waitingAdd = new List<SSAction> ();
	private List<int> waitingDelete = new List<int> ();

	public void Start() {
		SceneController.getControllerInstance ().setCCActionManager (this);
	}

	public void setCCAction(GameObject t, float s) {
		temp = t;
		speed = s;
		target = new Vector3 (-2, 20, 65);//飞碟飞向的目标
	}

	public void playDisk() {
		//if (temp.GetComponent<DiskData> ().getType ())
		temp.GetComponent<Rigidbody>().useGravity = false;
		ccAction = CCAction.GetSSAction (target, speed);
		RunAction (temp, ccAction);
	}

	protected void Update () {
		foreach (SSAction ac in waitingAdd)
			actions [ac.GetInstanceID ()] = ac;
		waitingAdd.Clear ();

		foreach (KeyValuePair <int, SSAction> kv in actions) {
			SSAction ac = kv.Value; 
			if (ac.destory) {
				waitingDelete.Add (ac.GetInstanceID ());
			} else if (ac.enable) {
				//Debug.Log ("This foreach!");
				ac.Update();
			}
		}

		foreach (int key in waitingDelete) {
			SSAction ac = actions [key];
			actions.Remove (key);
			DestroyObject (ac);
		}
		waitingDelete.Clear ();
	}

	public void RunAction (GameObject gameobject, SSAction action) {
		Debug.Log ("RunAction success");
		action.gameobject = gameobject;
		action.transform = gameobject.transform;
		waitingAdd.Add (action);
		action.Start ();
	}
}
5.SSAction:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SSAction : ScriptableObject {
	public bool enable = true;
	public bool destory = false;

	public GameObject gameobject { get; set; }
	public Transform transform{ get; set; }
	protected SSAction() {
	}

	public virtual void Start() {
		throw new System.NotImplementedException();
	}

	public virtual void Update() {
		throw new System.NotImplementedException();
	}
}
6.CCAction:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CCAction : SSAction {
	public Vector3 target;
	public float speed;

	public static CCAction GetSSAction(Vector3 target, float speed) {
		CCAction action = ScriptableObject.CreateInstance<CCAction> ();
		action.target = target;
		action.speed = speed;
		return action;
	}

	public override void Update() {
		this.transform.position = Vector3.MoveTowards (this.transform.position, target, speed);
		if (this.transform.position == target) {
			this.destory = true;
		}
	}

	public override void Start() {
	}
}
7.PhysicsActionManager:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhysicsActionManager : IActionManager {
	GameObject temp;
	Vector3 Force;
	Vector3 Dir;
	float emitSpeed;

	public void setPhysicsAction(GameObject t, Vector3 nextDir, float speed) {
		emitSpeed = speed;
		temp = t;
		nextDir.x *= Random.Range (-4f, 4f);
		Dir = nextDir;
		Force = nextDir * Random.Range (emitSpeed * 5, emitSpeed * 7) / 10;

	}

	public void playDisk() {
		temp.GetComponent<Rigidbody>().AddForce (Force, ForceMode.Impulse);
	}
}
8.DiskFactory:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DiskFactory : MonoBehaviour {
	private SceneController Controller;
	private List<GameObject> Used;
	private List<GameObject> Free;

	// Use this for initialization
	void Awake () {
		Used = new List<GameObject> ();
		Free = new List<GameObject> ();
		Controller = SceneController.getControllerInstance ();
		Controller.setFactory (this);
		//loadResource ();
	}

	public void setDisk(Color c, float speed, float size, int t) {
		for (int i = 0; i < Free.Count; i++) {
			Free [i].GetComponent<DiskData> ().setDisk (c, speed, size, t);
		}
		for (int i = 0; i < Used.Count; i++) {
			Used [i].GetComponent<DiskData> ().setDisk (c, speed, size, t);
		}
	}

	// Update is called once per frame
	void Update () {
		freeDisk ();
	}

	public void DisableDisk() {
		for (int i = 0; i < Used.Count; i++) {
			Used [i].SetActive (false);
		}
	}

	public GameObject getDisk() {
		GameObject temp;
		if (Free.Count != 0) {
			temp = Free [0];
			temp.SetActive (true);
			Free.RemoveAt (0);
		} else {
			temp = Instantiate (Resources.Load ("Prefabs/disk")) as GameObject;
			DiskData data = temp.GetComponent<DiskData> ();
			if (Controller.getRound() == 1)
				data.setDisk (Color.green, 0.5f, 1f, 1);
			else 
				data.setDisk (Color.red, 0.7f, 0.8f, 2);
			temp.SetActive (true); 
		}
		temp.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
		temp.GetComponent<Rigidbody> ().useGravity = true;
		Used.Add (temp);
		return temp;
	}

	void freeDisk() {
		int R = Controller.getRound ();
		for (int i = 0; i < Used.Count; i++) {
			GameObject temp = Used [i];
			//Debug.Log (Used [i].transform.position.y);
			if (!Used [i].activeInHierarchy) {
				temp.SetActive (false);
				Used.RemoveAt (i);
				Free.Add (temp);
			} else if (Used [i].transform.position.y < 0.5f || Used [i].transform.position.z > 60f) {
				Controller.getRecorder ().lostScore (temp);
				temp.SetActive (false);
				Used.RemoveAt (i);
				Free.Add (temp);
			}
		}
	}
}
9.DiskData:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DiskData : MonoBehaviour {
	Color color;
	float speed;
	float size;
	int DiskType;

	public void setDisk(Color c, float sp, float s, int t) {
		color = c;
		speed = sp;
		size = s;
		DiskType = t;
		Debug.Log (this.name);
		this.GetComponent<MeshRenderer>().material.color = c;
		Debug.Log ("SetDisk");
		this.transform.localScale = new Vector3 (1f * size, 0.1f, 1f * size);
	}

	public int getType() {
		return DiskType;
	}
}
10.ScoreRecorder:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScoreRecorder : MonoBehaviour {
	private SceneController Controller;
	private int Score;
	private int TotalScore;
	// Use this for initialization
	void Start () {
		Score = 0;
		TotalScore = 0;
		Controller = SceneController.getControllerInstance ();
		Controller.setRecorder (this);
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	public void getScore(GameObject d) {
		
		Score += 10 * d.GetComponent<DiskData> ().getType();
		Debug.Log (d.GetComponent<DiskData> ().getType ());
		TotalScore += 10 * d.GetComponent<DiskData> ().getType();
		if (Score >= 100) {
			Score = 0;
			Controller.nextRound ();
		}
		Debug.Log (Score);
	}

	public void lostScore(GameObject d) {
		Score -= 10 * d.GetComponent<DiskData> ().getType();
		TotalScore -= 10 * d.GetComponent<DiskData> ().getType();
	}

	public int returnScore() {
		return Score;
	}

	public int returnTScore() {
		return TotalScore;
	}
}










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值