Unity combat target game

Unity combat UFO game

Project source code

overall description

Use unity to realize a simple flying saucer game, and score when you hit the corresponding target. There are five arrows in one game.





Design ideas

The UML diagram is as follows

insert image description here





Define components

  1. bow and arrow

    Consists of two parts: the arrowhead and the arrow body.

    The arrow is a relatively small capsule that mounts the collider. The arrow body is a free material downloaded from the Assets Store

    insert image description here



  1. target

    Consisting of five concentric cylinders with different heights, each cylinder is mounted RingDataand corresponds to a different score

    insert image description here





Code

CCShootAction: Implement the launch event of the arrow

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: Realize archery action management

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: The trembling action after the arrow hits, called in the callback function

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);
        // }
    }
}

Specific application SSActionManagerin

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: Arrow factory, used to produce and release bows and arrows

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: Mounted on each ring, used to define the scores of different rings

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: Control ring impact events, scoring, callback trembling action

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";
    }
}

Guess you like

Origin blog.csdn.net/weixin_51930942/article/details/128179548