Unity3D学习(四)射箭游戏

然后是用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;
                }
            }
        }
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值