Juego de objetivos de combate de Unity

Unity combate juego de ovnis

código fuente del proyecto

Descripción general

Usa la unidad para realizar un simple juego de platillos voladores y anota cuando alcances el objetivo correspondiente. Hay cinco flechas en un juego.





Ideas de diseño

El diagrama UML es el siguiente

inserte la descripción de la imagen aquí





Definir componentes

  1. arco y flecha

    Consta de dos partes: la punta de flecha y el cuerpo de flecha.

    La flecha es una cápsula relativamente pequeña que monta el colisionador. El cuerpo de la flecha es un material gratuito descargado de la Tienda de activos

    inserte la descripción de la imagen aquí



  1. objetivo

    Compuesto por cinco cilindros concéntricos con diferentes alturas, cada cilindro está montado RingDatay corresponde a una puntuación diferente

    inserte la descripción de la imagen aquí





Código

CCShootAction: Implementar el evento de lanzamiento de la flecha.

public class CCShootAction : SSAction
{
    Vector3 force;
    Vector3 wind;

    private CCShootAction(){}

    // Start is called before the first frame update
    public override void Start()
    {
        gameObject.transform.parent = null;
        gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;

        // force = new Vector3(0, 0, 30);
        // Impulse:向此刚体添加瞬时力冲击,考虑其质量。
        gameObject.GetComponent<Rigidbody>().AddForce(force, ForceMode.Impulse);
        gameObject.GetComponent<Rigidbody>().AddForce(wind, ForceMode.Impulse);
        gameObject.GetComponent<Rigidbody>().isKinematic = false;
    }

    // Update is called once per frame
    public override void Update()
    {

    }

    public override void FixedUpdate(){
        // 箭飞到场外或者中靶
        if(this.transform.position.z > 35 || this.transform.tag == "onTarget"){
            Debug.Log("回调");
            this.destroy = true;
            this.enable = false;
            this.callback.SSActionEvent(this, SSActionEventType.Completed, 0, null, gameObject);
        }
    }

    public static CCShootAction GetSSAction(Vector3 wind){
        CCShootAction shoot = CreateInstance<CCShootAction>();
        shoot.force = new Vector3(0, 0, 40);
        shoot.wind = wind;
        return shoot;
    }
}


CCShootActionManager: Realice la gestión de la acción de tiro con arco.

public class CCShootActionManager : SSActionManager
{
    public FirstController firstController;
    public CCShootAction shoot;

    // Start is called before the first frame update
    protected void Start()
    {
        firstController = (FirstController)SSDirector.GetInstance().CurrentScenceController;
        firstController.actionManager = this;
    }

    public void Shoot(GameObject arrow, Vector3 wind){
        Debug.Log("Shoot");
        shoot = CCShootAction.GetSSAction(wind);
        this.RunAction(arrow, shoot, this);
    }
}


TrembleAction: La acción de temblor después de que golpea la flecha, llamada en la función de devolución de llamada

public class TrembleAction : SSAction
{
    float tremble_radius = 0.05f;
    float tremble_time = 0.5f; 
    GameObject arrow;

    Vector3 arrow_pos;

    private TrembleAction(){}
    public static TrembleAction GetSSAction()
    {
        TrembleAction tremble_action = CreateInstance<TrembleAction>();
        return tremble_action;

    }

    // Start is called before the first frame update
    public override void Start()
    {
        //得到箭中靶时的位置
        arrow_pos = gameObject.transform.position;
        // this.transform.Translate(new Vector3(0, 0, 0.5f));
        Debug.Log(gameObject.transform.name);
    }

    // Update is called once per frame
    public override void Update()
    {   
        tremble_time -= Time.deltaTime;
        //需要继续颤抖
        if(tremble_time > 0){
            // gameObject.transform.Translate(new Vector3(0.02f, 0, 0));
           
            Vector3 head_pos = gameObject.transform.position;

            float x = arrow_pos.x + Random.RandomRange(-0.05f, 0.05f);
            float y = arrow_pos.y + Random.RandomRange(-0.05f, 0.05f);
            float z = arrow_pos.z;
            gameObject.transform.position = new Vector3(x, y, z);
        }
        else{
            gameObject.transform.position = arrow_pos;
        }
        // else{
        //     transform.position = arrow_pos;
        //     this.destroy = true;
        //     this.callback.SSActionEvent(this);
        // }
    }
}

Aplicación específica SSActionManageren

public void SSActionEvent(SSAction source,
        SSActionEventType events = SSActionEventType.Completed,
        int intParam = 0,
        string strParam = null,
        GameObject arrow = null){
            TrembleAction trembleAction = TrembleAction.GetSSAction();
            this.RunAction(arrow, trembleAction, this);
        }


ArrowFactory: Fábrica de flechas, utilizada para producir y lanzar arcos y flechas.

public class ArrowFactory : MonoBehaviour
{
    private List<GameObject> used;
    private List<GameObject> free;
    public GameObject arrow;
    FirstController firstController;
    // Start is called before the first frame update
    void Start()
    {
        firstController = (FirstController)SSDirector.GetInstance().CurrentScenceController;
        used = new List<GameObject>();
        free = new List<GameObject>();
        arrow = null;
    }

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

    public GameObject GetArrow(){
        if(free.Count > 0){
            arrow = free[0];
            free.Remove(free[0]);
            if(arrow.tag == "onTarget")//箭在靶子上
            {
                arrow.GetComponent<Rigidbody>().isKinematic = false;
                arrow.tag = "arrow";
                arrow.transform.GetChild(0).gameObject.SetActive(true);
            }
            arrow.SetActive(true);
        }
        else{
            arrow = Instantiate(Resources.Load<GameObject>("Prefabs/arrow1"));
            arrow.GetComponent<Rigidbody>().isKinematic = false;
            // arrow.AddComponent<Rigidbody>();
        }
        // firstController = (FirstController)SSDirector.GetInstance().CurrentScenceController;
        // Transform pos = firstController.bow.transform.GetChild(0);
        // arrow.transform.position = pos.transform.position;
        arrow.transform.parent = firstController.bow.transform;   // 把arrow附加在bow上,跟随着bow移动
        arrow.transform.position = firstController.bow.transform.position;
        used.Add(arrow);

        return arrow;
    }

    public void FreeArrow(GameObject arrow){
        foreach(GameObject aa in used){
            Debug.Log("befreed");
            if(aa.gameObject.GetInstanceID() == arrow.GetInstanceID()){
                arrow.SetActive(false);
                used.Remove(aa);
                aa.tag = "arrow";
                break;
            }
        }
    }

    public void Clear(){
        foreach(GameObject dd in used){
            dd.transform.position = new Vector3(0, 0, 100);
            Destroy(dd);
        }
        foreach(GameObject dd in free){
            dd.transform.position = new Vector3(0, 0, 100);
            Destroy(dd);
        }
        used.Clear();
        free.Clear();
    }
}



RingData: Montado en cada anillo, se utiliza para definir las puntuaciones de diferentes anillos

public class RingData : MonoBehaviour {
    public int score;

    public void Start(){
        if(this.gameObject.name=="1"){
            score = 5;
        }
        else if(this.gameObject.name=="2"){
            score = 4;
        }
        else if(this.gameObject.name=="3"){
            score = 3;
        }
        else if(this.gameObject.name=="4"){
            score = 2;
        }
        else{
            score = 1;
        }
    }
}


RingController: Controle los eventos de impacto del anillo, la puntuación, las acciones de temblor de devolución de llamada

public class RingController : MonoBehaviour
{
    public ScoreRecorder scoreRecorder;
    public ISceneController sceneController;
    
    // Start is called before the first frame update
    void Start()
    {
        sceneController = SSDirector.GetInstance().CurrentScenceController as FirstController;
        scoreRecorder = Singleton<ScoreRecorder>.Instance;
        this.gameObject.AddComponent<RingData>();
    }

    // Update is called once per frame
    void OnTriggerEnter(Collider arrowCollider){
        Debug.Log("碰撞!");
        Transform arrow = arrowCollider.gameObject.transform.parent;
        Debug.Log(arrow.gameObject.name);
        if(arrow == null){
            Debug.Log("null");
            return;
        }
        scoreRecorder.RecordScore(this.gameObject.GetComponent<RingData>().score);
        Debug.Log("Score:"+this.gameObject.GetComponent<RingData>().score);

        
        arrow.GetComponent<Rigidbody>().isKinematic = true;
        arrow.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
        arrowCollider.gameObject.SetActive(false);
        arrow.tag = "onTarget";
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_51930942/article/details/128179548
Recomendado
Clasificación