Unity3D 重力下打飞碟

前言

本次完成,虽然具体实现不同,代码结构上,很大程度参考了大神的东西 ,所以复杂的东西也不写了,贴上代码以供自己以后使用;

Diskfactory.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace Com.Mygame {
    public class DiskFactory_C : System.Object {
        // diskes
        public List<GameObject> diskes = new List<GameObject>();
        // singleton
        private static DiskFactory_C _instance;
        public static DiskFactory_C GetInstance(){
            if (_instance == null) {
                _instance = new DiskFactory_C ();
            }
            return _instance;
        }
        // return a disk gameobject
        public GameObject getdisk_Canuse() {
            GameObject disk_temp;
            if (diskes.Count == 0) {
                //null and create one
                disk_temp = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                disk_temp.AddComponent<Rigidbody> ();
            } else { 
                disk_temp = diskes[0];
                diskes.RemoveAt (0);
            }
            return disk_temp;
        }
        // when disk be hit or download
        public void freeDisk(GameObject disk){
            disk.GetComponent<Rigidbody> ().velocity = Vector3.zero;
            disk.SetActive (false);
            diskes.Add (disk);
        }
    }
}

public class Diskfactory : MonoBehaviour {

}

GameModle.cs

这个cs文件主要控制了 飞碟的产生和使用

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Com.Mygame;

public class GameModle : MonoBehaviour {

    private List<GameObject> disks = new List<GameObject> ();
    private GameObject disk;
    private Vector3 size;
    private Vector3 pos;
    private Vector3 force;
    private Color color;

    //bullet part
    public GameObject bullet;

    private Vector3 force_b;
    private Vector3 pos_b;
    private Vector3 size_b;
    private Color color_b;

    private SceneController_C scene;
    private DiskFactory_C dc;

    //lanch a disk
    public void l_disk (){
        StartCoroutine (wait_to_lanch (3f));
    }

    IEnumerator wait_to_lanch(float waittime){
        yield return new WaitForSeconds (waittime);
        disk = DiskFactory_C.GetInstance ().getdisk_Canuse ();
        disk.SetActive (true);
        disk.transform.position = pos;
        disk.transform.localScale = size;
        disk.GetComponent<Renderer> ().material.color = color;

        disk.GetComponent<CapsuleCollider> ().isTrigger = true;

        disk.GetComponent<Rigidbody> ().mass = 0.1f;
        disk.GetComponent<Rigidbody> ().drag = 0.1f;
        disk.GetComponent<Rigidbody> ().angularDrag = 0.05f;
        disk.GetComponent<Rigidbody> ().velocity = Vector3.zero;
        disk.GetComponent<Rigidbody> ().AddForce (force,ForceMode.Impulse);
    }

    public void setting(Vector3 _size, Vector3 _pos, Vector3 _force,Color _color){
        size = _size;
        pos = _pos;
        force = _force;
        color = _color;
    }

    public void setting_b(Vector3 _size,Color _color){
        size_b = _size;
        color_b = _color;
    }

    // lanch a bullet
    public void l_bullet(Ray ray,Vector3 point) {
        if (bullet.active == false) {
            bullet.SetActive (true);
            bullet.transform.position = point;
            bullet.transform.localScale = size_b;

            //bullet.GetComponent<SphereCollider> ().isTrigger = true;

            bullet.GetComponent<Rigidbody> ().velocity = Vector3.zero;
            bullet.GetComponent<Rigidbody> ().mass = 0.01f;
            bullet.GetComponent<Rigidbody> ().drag = 0.01f;
            bullet.GetComponent<Rigidbody> ().angularDrag = 0f;
            bullet.GetComponent<Rigidbody> ().AddForce (ray.direction * 1f, ForceMode.Impulse);
        }
    }



    // Use this for initialization
    void Awake () {
        // zhu ru
        scene = SceneController_C.getInstance();
        scene.setGameModel (this);
        dc = DiskFactory_C.GetInstance ();
        //stting b
        setting_b(new Vector3(0.3f,0.3f,0.3f),Color.white);
        //
        bullet = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        bullet.AddComponent<Rigidbody> ();
        bullet.AddComponent<Judge> ();
        bullet.SetActive (false);
    }

    // Update is called once per frame
    void Update () {
        if (disk != null && disk.active == true) {
            if (disk.transform.position.y < -3f) {
                dc.freeDisk (disk);
                scene.Misshit ();
            }
        }

        if(disk != null && bullet.transform.position.z > disk.transform.position.z+10f){
            bullet.SetActive (false);
        }
    }

}

Judge.cs

using UnityEngine;
using System.Collections;
using Com.Mygame;

public class Judge : MonoBehaviour {

    private SceneController_C scene;
    private DiskFactory_C disckf;
    private PFactory_C pfactory;

    // Use this for initialization
    void Start () {
        scene = SceneController_C.getInstance ();
        disckf = DiskFactory_C.GetInstance ();
        pfactory = PFactory_C.GetInstance ();
    }
    // Update is called once per frame
    void Update () {

    }

    void OnTriggerEnter(Collider other) {
        GameObject obj = other.gameObject;
        getScore (obj);
        pfactory.Boom (obj.transform.position);
    }

    void getScore(GameObject obj) {
        scene.Ifhit ();
        disckf.freeDisk (obj);
    }

    void missDisk(GameObject obj) {
        disckf.freeDisk (obj);
    }

}

Pfactory.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Com.Mygame;

namespace Com.Mygame {
    public class PFactory_C : System.Object {
        public List<GameObject> cubes = new List<GameObject>();

        private static PFactory_C _instance;
        public static PFactory_C GetInstance(){
            if(_instance == null){
                _instance = new PFactory_C ();
            }
            return _instance;
        }

        public GameObject getcube() {
            GameObject cube;
            if (cubes.Count == 0) {
                cube = GameObject.CreatePrimitive (PrimitiveType.Cube);
                cube.AddComponent<Rigidbody> ();
                cube.AddComponent<PFactory> ();
                cube.GetComponent<BoxCollider> ().isTrigger = true;
                //cube.transform.localScale = new Vector3 (0.3f,0.3f,0.3f);

            } else {
                cube = cubes [0];
                cubes.RemoveAt (0);

            }
            return cube;
        }

        public void freeCube(GameObject cube) {
            cube.GetComponent<Rigidbody> ().velocity = Vector3.zero;
            cube.SetActive (false);

            cubes.Add (cube);
        }

        public void Boom(Vector3 pos){
            for(int i = 0; i<=40; i++){
                GameObject cube = _instance.getcube ();
                cube.SetActive (true);
                cube.transform.position = pos;
                float l_size = Random.Range (0.2f,0.5f);
                //Debug.Log (l_size);
                cube.transform.localScale = new Vector3(l_size,l_size,l_size);
                if (SceneController_C.getInstance ().getRound () == 2)
                    cube.GetComponent<Renderer> ().material.color = Color.blue;
                else if (SceneController_C.getInstance ().getRound () == 3) 
                    cube.GetComponent<Renderer> ().material.color = Color.red;
                else 
                    cube.GetComponent<Renderer> ().material.color = Color.gray;

                cube.GetComponent<Rigidbody> ().AddForce (Random.onUnitSphere*6,ForceMode.Impulse);
            }
        }

        IEnumerator wait_to_lanch(float waittime,GameObject cube){
            yield return new WaitForSeconds (waittime);
            freeCube (cube);
        }


    }
}

public class PFactory : MonoBehaviour {
    private PFactory_C pc;
    // Use this for initialization
    void Start () {
        pc = PFactory_C.GetInstance ();
    }

    // Update is called once per frame
    void Update () {
        if (this.gameObject.transform.position.y < -3f) {
            pc.freeCube (this.gameObject);
        }   
    }
}

SceneControll.cs

using UnityEngine;
using System.Collections;
using Com.Mygame;

namespace Com.Mygame {
    // inerface
    public interface IUserInterface {
        void lanch_disk();
        void lanch_bullet(Ray ray,Vector3 point);
    }

    public interface IQueryStates {
        int getRound();
        int getScore();
        int getTime();
        int getHit ();
        bool getIs_shooting();
    }

    public interface IJudgeEvent {
        void nextRound();
        void Ifhit ();
        void Misshit ();
        //bool Is_hitted (); // if the bullet hit the disk,the return true
    }

    public class SceneController_C : System.Object,IQueryStates,IJudgeEvent,IUserInterface {
        private static SceneController_C _instance;
        private SceneController _base;
        private GameModle _gameModel;
        private int _round = 1;
        private int _score;
        private int _hit = 0;
        private int _time;
        private bool Is_shooting = false;

        public static SceneController_C getInstance() {
            if(_instance == null){
                _instance = new SceneController_C ();
            }
            return _instance;
        }

        // zhu ru
        public void setGameModel(GameModle obj) {
            _gameModel = obj;
        }
        internal GameModle getGameModel() {
            return _gameModel;
        }

        public void setSceneController (SceneController sc){
            _base = sc;
        }

        // Iuserinterface contorl
        public void lanch_disk() {
            Is_shooting = true;
            _base.loadRoundDate (_round);
            _gameModel.l_disk ();
        }
        public void lanch_bullet(Ray ray,Vector3 point){
            _gameModel.l_bullet (ray,point);
        }

        // Iquery
        public int getRound() { return _round; }
        public int getScore() { return _score; }
        public int getTime() { return _time; }
        public int getHit() { return _hit; }
        public bool getIs_shooting() { return Is_shooting; }

        // IJudgeEvent

        public void nextRound(){
            _hit = 0;
            if (_round != 3) {
                _round++;
            } else {
                _round = 1;
                _score = 0;
            }
        }

        public void Ifhit(){
            _score++;
            _hit++;
            Is_shooting = false;
        }

        public void Misshit(){
            _hit++;
            Is_shooting = false;
        }

    }

}

public class SceneController : MonoBehaviour {

    private Color color;
    private Vector3 lanchPos;
    private Vector3 lanchForce;
    private Vector3 lanchSize;

    private SceneController_C scene;

    void Awake(){
        scene = SceneController_C.getInstance ();
        scene.setSceneController (this);
    }

    public void loadRoundDate(int round){
        Vector3 pos = new Vector3 (0f,-2f,-7f);
        Vector3 little = new Vector3 (1f,0f,0f);
        switch(round){
        case 1:
            float Rankey = Random.Range (-2f,2f);
            color = Color.gray;
            lanchPos = pos;
            lanchSize = new Vector3 (3f,0.5f,3f);
            lanchForce = new Vector3(0,1.5f,1.5f) + Rankey*little;
            SceneController_C.getInstance ().getGameModel ().setting (lanchSize,lanchPos,lanchForce,color);
            break;
        case 2:
            float Rankey2 = Random.Range (-2f,2f);
            color = Color.blue;
            lanchPos = pos;
            lanchSize = new Vector3 (2f,0.5f,2f);
            lanchForce = new Vector3(0,1.7f,1.7f) + Rankey2*little;
            SceneController_C.getInstance ().getGameModel ().setting (lanchSize,lanchPos,lanchForce,color);
            break;
        case 3:
            float Rankey3 = Random.Range (-2f,2f);
            color = Color.red;
            lanchPos = pos;
            lanchSize = new Vector3 (1.5f,0.3f,1.5f);
            lanchForce = new Vector3(0,2f,2f) + Rankey3*little;
            SceneController_C.getInstance ().getGameModel ().setting (lanchSize,lanchPos,lanchForce,color);
            break;
        }
    }

    void Update(){
        if (scene.getHit () == 3) {
            scene.nextRound (); 
        }
    }
}

UserInterface.cs

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using Com.Mygame;

//userinterface is use to 1. inpuut 2.score,Time,round
//input : 1.space 2. mousedown
public class UserInterface : MonoBehaviour {
    public Text scoreText;
    public Text roundText;
    public Text timeText;

    private int round;

    //interface
    private IUserInterface userInt;
    private IQueryStates queryInt;

    // Use this for initialization

    void Start () {
        // here is how to make interface reqire
        userInt = SceneController_C.getInstance () as IUserInterface;
        queryInt = SceneController_C.getInstance () as IQueryStates;
    }

    // Update is called once per frame
    void Update () {
        // space to lanch a disk
        if (queryInt.getIs_shooting() == false) {
            if(Input.GetKeyDown("space")){
                userInt.lanch_disk ();

            }
        }
        if(Input.GetMouseButtonDown(0)){
            Ray ray = new Ray ();
            ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            Vector3 point = new Vector3 ();
            point = Camera.main.transform.position;
            userInt.lanch_bullet (ray,point);
        }

        roundText.text = "Round: " + queryInt.getRound ().ToString();
        scoreText.text = "Score: " + queryInt.getScore ().ToString();
    }

}

你可能感兴趣的:(unity3d)