然后是用rigidbody的处理来实现一个射箭游戏
这里贴上游戏效果和代码
ArrowController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class ArrowController {
GameObject arrow;
Vector3 startPos;
ArrowScript arrowScript;
Vector3 resetForce;
public ArrowController(GameObject obj) {
arrow = obj;
startPos = new Vector3 (0, 0, 0);
arrow.transform.position = startPos;
arrowScript = obj.AddComponent<ArrowScript> ();
obj.AddComponent<MoveAction> ();
arrowScript.arrow = this;
resetForce = new Vector3 (0, 0, -10);
}
public GameObject getGameObj() {
return arrow;
}
public void appear() {
this.arrow.SetActive (true);
}
public void disappear() {
this.arrow.SetActive (false);
}
public void setPosition(Vector3 pos) {
this.arrow.transform.position = pos;
}
public Rigidbody getRigidBody() {
return arrow.GetComponent<Rigidbody> ();
}
public void reset() {
Debug.Log ("reset...");
// this.arrow.AddComponent<Rigidbody> ();
// this.arrow.transform.position = startPos;
this.getRigidBody ().AddForce (resetForce);
}
}
}
ArrowFactory.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class ArrowFactory : MonoBehaviour {
Queue<ArrowController> freeQueue;
List<ArrowController> usingList;
GameObject originalArrow;
Vector3 startPos;
void Awake() {
freeQueue = new Queue<ArrowController> ();
usingList = new List<ArrowController> ();
originalArrow = Object.Instantiate (Resources.Load ("prefabs/arrow", typeof(GameObject))) as GameObject;
// originalArrow.AddComponent<BoxCollider> ();
originalArrow.AddComponent<OnCollision> ();
originalArrow.AddComponent<Rigidbody> ();
originalArrow.GetComponent<Rigidbody> ().collisionDetectionMode = CollisionDetectionMode.Continuous;
originalArrow.GetComponent<Rigidbody> ().useGravity = false;
// originalArrow.GetComponent<Collider> ().isTrigger = true;
originalArrow.SetActive (false);
startPos = new Vector3 (0, 0, 0);
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public ArrowController produceArrow() {
Debug.Log ("producing arrow...");
ArrowController newArrow;
newArrow = null;
if (freeQueue.Count == 0) {
GameObject newObj = GameObject.Instantiate (originalArrow);
// newObj.AddComponent<MoveAction> ();
newArrow = new ArrowController (newObj);
} else {
newArrow = freeQueue.Dequeue ();
}
newArrow.appear ();
// newArrow.setPosition (startPos);
usingList.Add (newArrow);
return newArrow;
}
public void recycle (ArrowController arrow) {
Debug.Log ("recycle in ArrowFactory...");
arrow.disappear ();
arrow.reset ();
arrow.getGameObj ().transform.position = startPos;
usingList.Remove (arrow);
freeQueue.Enqueue (arrow);
}
}
}
ArrowScript.cs(也是为了能从GameObject获取到Controller)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class ArrowScript : MonoBehaviour {
public ArrowController arrow;
// Use this for initialization
void Start () {
for (int i = 0; i < transform.childCount; i++)
{
GameObject g = transform.GetChild(i).gameObject;
g.AddComponent<ArrowScript>().arrow = arrow;
}
}
// Update is called once per frame
void Update () {
}
}
}
Director.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class Director : System.Object {
private static Director director;
public SceneController currentSceneController;
public static Director getInsance() {
if (director == null) {
director = new Director ();
}
return director;
}
}
}
FirstSceneController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using game;
namespace game {
public class FirstSceneController : MonoBehaviour, SceneController, userAction {
Director director;
ArrowController arrow;
ArrowFactory af;
MoveAction ma;
GameObject target;
GameObject ground;
GameObject wall;
Scorer scorer;
UserGUI UI;
GameObject canvas;
Text scoreText;
OnCollision oc;
// TargetController target;
// Use this for initialization
void Awake() {
Director director = Director.getInsance ();
director.currentSceneController = this;
}
public void loadResources() {
target = GameObject.Instantiate (Resources.Load("prefabs/targetBasis")) as GameObject;
// target.AddComponent<Rigidbody> ();
// target.AddComponent<OnCollision> ();
// target.GetComponentInChildren<Collider> ().isTrigger = true;
target.transform.position = new Vector3 (0, 0.3f, 0);
ground = GameObject.Instantiate (Resources.Load("prefabs/ground")) as GameObject;
wall = GameObject.Instantiate (Resources.Load("prefabs/wall")) as GameObject;
}
void Start () {
loadResources ();
af = GetComponent<ArrowFactory> ();
ma = GetComponent<MoveAction> ();
scorer = GetComponent<Scorer> ();
UI = GetComponent<UserGUI> ();
oc = GetComponent<OnCollision> ();
// oc.target = target;
canvas = GameObject.Instantiate (Resources.Load("prefabs/Canvas")) as GameObject;
scoreText = canvas.transform.Find ("Score").GetComponent<Text> ();
scoreText.text = "Score: 0";
}
// Update is called once per frame
void Update () {
scoreText.text = "Score: " + scorer.getScore ();
}
public void startGame() {
Debug.Log ("Game starts...");
nextShoot ();
}
public void OnCollision(GameObject obj) {
// Debug.Log (obj.GetComponent<MeshRenderer>().material.color);
Debug.Log ("The obj name is " + obj.name);
scorer.addScore (obj);
}
public void nextShoot() {
arrow = af.produceArrow ();
ma = arrow.getGameObj ().GetComponent<MoveAction> ();//test
Debug.Log("arrow is " + arrow.ToString());
// Debug.Log ("judgement: "+ (arrow==null).ToString());
ma.setArrow (arrow);
Debug.Log ("ma's Arrow is "+arrow.ToString());
ma.setShot (false);
oc.setFlag (false);
// nextShoot ();
}
public void recycle (ArrowController arrow) {
// ma = arrow.getGameObj ().GetComponent<MoveAction> ();//test
Debug.Log ("recycling..." + arrow);
if (arrow != null) {
af.recycle (arrow);
}
}
}
}
interface.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public interface userAction {
void startGame();
}
public interface SceneController {
void loadResources();
}
}
MoveAction.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class MoveAction : MonoBehaviour {
public ArrowController arrow;
public GameObject arr;
Vector3 force;
bool shot = false;
Camera cam;
// Use this for initialization
void Start () {
force = new Vector3 (0, 0, 10);
shot = false;
arrow = null;
arr = this.gameObject;
cam = Camera.main;
}
// Update is called once per frame
void Update () {
// this.transform.Find ("head").LookAt (Input.mousePosition);
// print(this);
// this.transform.LookAt (Input.mousePosition);
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
// print (this.name);
// this.transform.rotation = Quaternion.FromToRotation(Vector3.down, ray.direction);
// Debug.Log(shot);
Debug.Log ("test of " + shot.ToString());
if (!shot && this.name == "arrow(Clone)(Clone)") {
// Debug.Log ("set rotation...");
this.transform.rotation = Quaternion.FromToRotation (Vector3.forward, ray.direction);
}
// Debug.DrawRay (cam.transform.position, Input.mousePosition,Color.blue);
// arrow.transform.rotation = Quaternion.FromToRotation(Vector3.up * -1, ray.direction);
if (Input.GetMouseButtonDown(0)) {
// Debug.Log ("Button down...");
shot = true;
}
}
public void setShot(bool flag) {
shot = flag;
}
public void setArrow(ArrowController arr) {
Debug.Log ("setting new arrow...");
arrow = arr;
}
void FixedUpdate() {
// Debug.Log ("current arrow: " + this.arrow.ToString());
// Debug.Log ("judgement: "+ (arrow==null).ToString());
// if (arrow == null)
// return;
if (arr == null)
return;
// Rigidbody rigid = arrow.getRigidBody();
Rigidbody rigid = arr.GetComponent<Rigidbody> ();
Debug.Log ("RigidBody is " + rigid.ToString());
if (rigid && shot) {
// Debug.Log (shot);
Debug.Log ("Adding the force");
rigid.AddForce (force);
}
}
}
}
OnCollision.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class OnCollision : MonoBehaviour {
FirstSceneController sceneController;
GameObject obj;
bool flag; // 判断是否碰到第一个
// public GameObject target;
// Use this for initialization
void Start () {
Debug.Log ("OnCollision started...");
sceneController = Director.getInsance ().currentSceneController as FirstSceneController;
flag = false;
}
// Update is called once per frame
void Update () {
}
public void setFlag(bool f) {
flag = f;
}
void OnCollisionEnter(Collision collision) {
if (flag)
return;
// Debug.Log (collision.collider.gameObject.name);
if (collision.collider.gameObject.name == "wall(Clone)") {
sceneController.recycle (this.gameObject.GetComponent<ArrowScript> ().arrow);
Debug.Log ("next...");
sceneController.nextShoot ();
return;
// sceneController.recycle (this);
}
Debug.Log ("Collision...");
Destroy (this.GetComponent<Rigidbody> ());
obj = collision.collider.gameObject;
// GameObject target = collision.collider.transform.parent.gameObject;
// Component[] comp = target.GetComponentsInChildren<Collider> ();
// Debug.Log (comp.Length);
// foreach (Collider i in comp) {
Debug.Log ("Disabed one round...");
// if (i.gameObject.name.StartsWith("target")) i.enabled = false;
// }
sceneController.OnCollision (obj);
flag = true;
if (flag) {
Debug.Log ("next...");
sceneController.nextShoot ();
}
// if (collision.collider.name == "target")
// parent = collision.collider.transform.parent;
// if (collision.collider.name == "arrow(Clone)(Clone)") {
// Debug.Log ("Destroy Rigidbody...");
// Destroy (collision.collider.gameObject.GetComponent<Rigidbody> ());
// }
// Debug.Log ("Enter the OnCollisionEnter...");
// Debug.Log ("GameObject is : " + collision.gameObject.name);
// if (collision.collider) {
// Debug.Log ("Collider belongs to : " + collision.collider.gameObject.name);
// }
// if (collision.rigidbody) {
// Debug.Log ("Rigidbody belongs to : " + collision.rigidbody.gameObject.name);
// }
// foreach(ContactPoint contact in collision.contacts) {
// Debug.Log ("show rays...");
// Debug.DrawRay (contact.point, contact.normal, Color.blue);
// }
}
// void OnTriggerEnter(Collider collider) {
// Debug.Log ("Collision...");
// // if (collision.collider.name == "target")
// // parent = collision.collider.transform.parent;
// // if (collision.collider.name == "arrow(Clone)(Clone)") {
// // Debug.Log ("Destroy Rigidbody...");
// // Destroy (collision.collider.gameObject.GetComponent<Rigidbody> ());
// // }
// // Debug.Log ("Enter the OnCollisionEnter...");
// Debug.Log ("GameObject is : " + collider.gameObject.name);
if (collider) {
Debug.Log ("Collider belongs to : " + collider.gameObject.name);
}
// // foreach(ContactPoint contact in collision.contacts) {
// // Debug.Log ("show rays...");
// // Debug.DrawRay (contact.point, contact.normal, Color.blue);
// // }
// }
}
}
Scorer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class Scorer : MonoBehaviour {
int score;
// Use this for initialization
void Start () {
score = 0;
}
// Update is called once per frame
void Update () {
}
public int getScore() {
return score;
}
public void addScore(GameObject obj) {
if (obj.name.StartsWith("target0")) {
score += 1;
} else if (obj.name.StartsWith("target1")) {
score += 2;
} else if (obj.name.StartsWith("target2")) {
score += 3;
} else if (obj.name.StartsWith("target3")) {
score += 4;
} else if (obj.name.StartsWith("target4")) {
score += 5;
}
}
}
}
UserGUI.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using game;
namespace game {
public class UserGUI : MonoBehaviour {
userAction action;
bool started;
// Use this for initialization
void Start () {
action = Director.getInsance ().currentSceneController as userAction;
started = false;
}
// Update is called once per frame
void Update () {
}
void OnGUI() {
if (!started) {
if (GUI.Button(new Rect (Screen.width / 2 - 70, Screen.height / 2, 140, 70), "start")) {
action.startGame ();
started = true;
}
}
}
}
}