Mouse playing flying saucer (physics engine)

Improve the mouse to play UFO

1. Game Requirements

1. Modify the flying saucer game according to the design diagram of the adapter mode.

2. Make it support physical movement and kinematic movement at the same time.

Adapter mode: convert the interface of a class into another interface that the customer wants, so that those classes that could not work together due to incompatible interfaces can work together.

Its UML diagram is as follows:

insert image description here

It is to change the interface of the original project so that it can support physical movement and kinematic movement.

2. Game implementation

​ To make the flying saucer support physical movement and kinematic movement, the rigid body Rightbody component is needed, so that we can apply force to the object to control the flying saucer with realistic physical effects, and also make the flying saucer respond to collisions, making it more realistic.

​ And the Rightbody cannot be updated with the Update function. It needs to be updated with the Fixedupdate function. FixedUpdate is called before each physical update, so any changes made in this function will be processed directly.

3. Specific implementation

Only the code that is different from the previous assignment is shown below.

  1. First, prefabricate the Frisbee and add the Rigidbody (Rightbody) component.

insert image description here

  1. PhysicsDiskFlyAction

    It specifies the movement of the flying saucer. When the flying saucer flies into the screen from the left, give the flying saucer a force to the left. When the flying saucer flies into the screen from the right, give the flying saucer a force to the right. When the flying saucer flies out of the screen, set the flying saucer speed to 0 and destroy the flying saucer. The main difference from the last job is that the rigid body component is added, and the state of the flying saucer is updated with the fixupdate function.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    // 模拟飞行
    public class PhysicsDiskFlyAction : SSAction {
     private Vector3 start_vector;                              
     public float power;
     private PhysicsDiskFlyAction() { }
     public static PhysicsDiskFlyAction GetSSAction(int lor, float power) {
         PhysicsDiskFlyAction action = CreateInstance<PhysicsDiskFlyAction>();
         if (lor == -1) action.start_vector = Vector3.left * power;
         else action.start_vector = Vector3.right * power;
         action.power = power;
         return action;
     }
    
     public override void Update() { }
    
     public override void FixedUpdate() {
         if (transform.position.y <= -10f) {
             gameobject.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
             this.destroy = true;
             this.callback.SSActionEvent(this);
         }
     }
    
     public override void Start() {
         gameobject.GetComponent<Rigidbody>().AddForce(start_vector*3, ForceMode.Impulse);
     }
    }
    
    
  2. SSAction

    Add the FixedUpdate function to adapt it to the physics engine.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    //动作基类
    public class SSAction : ScriptableObject {
        public bool enable = true;                      
        public bool destroy = false;                    
    
        public GameObject gameobject;                   
        public Transform transform;                     
        public ISSActionCallback callback;              
    
        
        protected SSAction() { }
    
        public virtual void Start() {
            throw new System.NotImplementedException();
        }
    
        public virtual void Update() {
            throw new System.NotImplementedException();
        }
        public virtual void FixedUpdate() {
            throw new System.NotImplementedException();
        }
    }
    

4.SSActionManager

​ Add the FixedUpdate function to the update function to adapt it to the physics engine.

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

/*动作管理基类*/
public class SSActionManager : MonoBehaviour, ISSActionCallback {
    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();    
    private List<SSAction> waitingAdd = new List<SSAction>();                      
    private List<int> waitingDelete = new List<int>();                                             

    protected void Update() {
        foreach (SSAction ac in waitingAdd) {
            actions[ac.GetInstanceID()] = ac;
        }
        waitingAdd.Clear();

        foreach (KeyValuePair<int, SSAction> kv in actions) {
            SSAction ac = kv.Value;
            if (ac.destroy) {
                waitingDelete.Add(ac.GetInstanceID());
            }
            else if (ac.enable) {
                ac.Update();
                ac.FixedUpdate();
            }
        }
        
        foreach (int key in waitingDelete) {
            SSAction ac = actions[key];
            actions.Remove(key);
            Object.Destroy(ac);
        }
        waitingDelete.Clear();
    }

    public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager) {
        action.gameobject = gameobject;
        action.transform = gameobject.transform;
        action.callback = manager;
        waitingAdd.Add(action);
        action.Start();
    }

    public void SSActionEvent(
        SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null) {
    }
}

5.DiskFlyActionManager

To manage the flying saucer action, introduce the PhisicsDiskFlyAction action written above and rewrite the DiskFly function. Used to manage the movements of the flying saucer.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DiskFlyActionManager : SSActionManager
{
    public PhysicsDiskFlyAction ph_fly;
    public FirstController scene_controller;
    protected void Start()
    {
        scene_controller = (FirstController)SSDirector.GetInstance().CurrentScenceController;
        scene_controller.myactionmanager = this;
    }
    

    public void DiskFly(GameObject disk, float power)
    {
        disk.GetComponent<Rigidbody>().isKinematic = false;
        int loc = disk.transform.position.x < 0 ? 1 : -1;
        ph_fly = PhysicsDiskFlyAction.GetSSAction(loc, power);
        this.RunAction(disk, ph_fly, this);
    }
}

code and demo

Code location Drag the assets of hw6 into the project, then open myscene in Resources, and run it.

demo video

Guess you like

Origin blog.csdn.net/weixin_52801288/article/details/128104839