3D game programming and design assignment 6

Improve the UFO (Hit UFO) game

Claim

  1. Modify the flying saucer game according to the adapter mode design drawing
  2. Make it support both physical movement and kinematics (transformation) movement

achieve

Original project: 3D Programming and Game Design Assignment 5 It
can be realized only by changing some of the classes.

UFO preset

Due to the requirement to support physical movement, the default setting of the flying saucer needs to add a rigid body to the original basis:
Insert picture description here

Implementation of Adapter

The adapter selects different interfaces through different states. In this assignment, different action implementation methods (physical/kinematics) are selected. It is found that the function is similar to the previous flyActionController, so it is rewritten as Adapter:

public class Adapter : SSActionManager {
    public DiskFlyAction fly;
    public PhysisFlyAction fly_;

    public void DiskFly(GameObject disk, int mode, mes information) {
        int leftOrRight = 1;
        if (disk.transform.position.x > 0){
            leftOrRight = -1;
        }

        if(mode == 2){
            fly = DiskFlyAction.GetSSAction(leftOrRight, information.angle, information.speed);
            this.StartAction(disk, fly);
        }
        else{
            fly_ = PhysisFlyAction.GetSSAction(leftOrRight, information.speed);
            this.StartAction(disk, fly_);
        }
    }
}

Control the movement type through mode, and then call DiskFlyAction and PhysisFlyAction respectively. The information used here is a custom type to store related information.

public struct mes{
    public float speed;
    public float angle;
}

PhysisFlyAction && SSAction && DiskFlyAction

The PhysisFlyAction class, the code is as follows:

public class PhysisFlyAction : SSAction
{
    private bool start_position;
    public float force;

    public static PhysisFlyAction GetSSAction(int pos, float force_){
        PhysisFlyAction action = CreateInstance<PhysisFlyAction>();
        if(pos == 1){
            action.start_position = true;
        }
        else{
            action.start_position = false;
        }
        action.force = force_;
        
        return action;
    }
    // Start is called before the first frame update
    public override void Start()
    {
        Rigidbody disk = gameobject.GetComponent<Rigidbody>();
        
        gameobject.GetComponent<Rigidbody>().useGravity = true;
        if(gameobject.GetComponent<Rigidbody>().position.y <= 3){
            if(start_position){
                gameobject.GetComponent<Rigidbody>().AddForce(new Vector3(0.4f,0.2f,0)*force*15f, ForceMode.Impulse);
            }
            else{
                gameobject.GetComponent<Rigidbody>().AddForce(new Vector3(-0.4f,0.2f,0)*force*15f, ForceMode.Impulse);
            }
        }
    }

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

    public override void FixedUpdate() {
        if (transform.position.y <= -10f) {
            Debug.Log(transform.position.y);
            gameobject.GetComponent<Rigidbody>().useGravity = false;
            gameobject.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
            this.enable = false;
        }
    }
}

The overall implementation is similar to the physical movement, but FixedUpdate is used here.
The small details of this type of design have changes to gravity. In the start, gravity is turned on. Under the action of an initial force and gravity, the flying saucer makes a projectile motion. When the flying saucer moves out of the line of sight of our camera (here is FixedUpdate) When mentioned -10f), the gravity is turned off. Because if the gravity is not turned off, the flying saucer will continue to fall, and then it will have a great speed when DiskFactory recycles the flying saucer for the next use, which will affect the game experience, as shown in the figure below (you can see the third green flying saucer appears in the lower right corner Has a very large vertical speed when, flashes past):
Insert picture description here

Since physic adds FixedUpdate, SSAction and DiskFlyAction also add an empty FixedUpdate:

public class SSAction : ScriptableObject {
	……    
    public virtual void FixedUpdate() {
        throw new System.NotImplementedException();
    }
    ……
}

public class DiskFlyAction : SSAction {
	……
    public override void FixedUpdate() {
        
    }
    ……
}

FirstController && Interfaces

The changes of FirstController are as follows:
a bool variable is added to record whether it is a physical movement or a kinematic transformation movement. In order to change this variable through UserGUI, a setPhysic function is added, and at the same time, it is added to Interfaces to facilitate UserGUI modification.

private bool physic = false;
……
public void setPhysic(bool physic_){
	physic = physic_;
}

SSActionManager

Increase FixedUpdate:

……
if (action.enable) {
    	action.Update();
    	action.FixedUpdate();
} 
……

UserGUI

Two buttons are added to the first interface to select whether it is in physic mode.


effect

Physic mode: The
Insert picture description here
original kinematics mode is still running normally:
Insert picture description here

Source code:

GitHub

Guess you like

Origin blog.csdn.net/Floating__dust/article/details/109633997