unity demo free download: third person lens movement + line of sight + launch arc ball to hit the box (the box can identify the direction of attack) demo

Posted by anne13 on Sun, 06 Feb 2022 22:37:22 +0100

Unity: third person vision movement + line of sight + firing arc ball to hit the box (the box can identify the direction of attack) demo

Function Description:

  • The camera can move according to the mouse sliding (similar to the third person game lens control)

  • A small ball that emits an arc

  • The camera field of view has an auxiliary line (line of sight, similar to the line of sight of angry birds)

  • The box can judge which direction was hit

demonstration


demo version 1.0

demo version 2.0

Description supplement and download link

Two scene resource packages, free download

Network disk link:

Link: https://pan.baidu.com/s/1P9Uj7i6v-NPlrIB6rE-0Dg
Extraction code: f8sd

The first one uses the method of manually adding force and giving initial speed (without gravity). The trajectory of the small ball launched from different angles is the same (before touching the object), and the movement of the small ball after touching the object is more dreamy. I wrote the code myself.

In the second scene, gravity is used. The small ball is launched from different angles, and the trajectory is different. The small ball will fall when it touches an object. Because of the temporary change of the project, gravity was used instead. Due to the lack of time, someone else's code was used in the calculation track [unity] precomputed rigid body trajectory_ Xiao ran - CSDN blog_ Unity trajectory

Some details

Bullet firing part (note that the code for applying force is finally put in FixedUpdate, which is very important, and will be explained briefly later)

  • Because the lens will move, it needs to be controlled by a rigid body, and the target position is not fixed, it is not as simple as I thought to realize the arc motion of the bullet

(this method has been deprecated)

In the Fire class

//Forward movement
bulletSon.GetComponent<Rigidbody>().velocity = bulletSon.transform.forward * speedZ;

In the new bullet class, the force in the vertical direction with the new bullet itself

private void Update()
{
       t += Time.deltaTime;
       deltaForce = 1f / 2 * a * t * t;
       gameObject.GetComponent<Rigidbody>().AddForce(gameObject.transform.up * (gameObject.GetComponent<BulletParameter>().deltaForce*(-1)));
}

(deprecated)

In fact, AddForce needs to exist all the time to achieve the effect of force in real life. If AddForce is called only once in the function, it is equivalent to only attaching an initial speed.

(this method is used now)

Then slightly optimize the structure and put the speed in the bullet class

public class BulletParameter : MonoBehaviour
{
    public float deltaForce = 0 ;
    private float a = 10.5f;
    private float t = 0;
    private float speedFront = 9f;

    private void Start()
    {
        //It cannot be placed in update, which will overwrite the speed
        //Forward movement
        gameObject.GetComponent<Rigidbody>().velocity = transform.forward * speedFront;
    }
    private void Update()
    {
        t += Time.deltaTime;
        deltaForce = 1f / 2 * a * t * t;
        //Equivalent to its own vertical direction
        gameObject.GetComponent<Rigidbody>().AddForce(gameObject.transform.up * (gameObject.GetComponent<BulletParameter>().deltaForce*(-1)));
    }
}

It's just that when the bullet collides with an object, it will fly around like a ghost. It's very interesting. If you use world coordinates, it should not be the case, but in this case, you need to change the control mode of the lens, which does not meet the demand.

(final method)

If the horizontal throwing motion is required, it is very important that the force is placed in FixedUpdate, otherwise the auxiliary line calculated according to the formula will not coincide with the motion track!

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

public class BulletParameter : MonoBehaviour
{
    private float speedFront = 9f;//Speed of forward movement
    private float forceVertical = -0.3f;//Vertical force

    //Deprecated
    //public float deltaForce = 0 ;// Change of force
    //private float a = 11f;// Rate of change of force
    //private float t = 0;// Exercise time
    

    private void Start()
    {
        //It cannot be placed in update, which will overwrite the speed
        //Forward movement
        gameObject.GetComponent<Rigidbody>().velocity = transform.forward * speedFront;
    }
    private void FixedUpdate()
    {
        //t += Time.deltaTime;
        //deltaForce = 1f / 2 * a * t * t;
        //It is equivalent to its own vertical direction, which is a kind of horizontal throwing motion
        //gameObject.GetComponent<Rigidbody>().AddForce(gameObject.transform.up * (gameObject.GetComponent<BulletParameter>().deltaForce*(-1)));
        //This is a flat throwing motion
        gameObject.GetComponent<Rigidbody>().AddForce(gameObject.transform.up * forceVertical);
    }
}

  • Bullet firing requires continuous collision detection
bulletSon.GetComponent<Rigidbody>().collisionDetectionMode = CollisionDetectionMode.Continuous;//bulletSon is my own bullet class
  • Making the coordinates of the bullet consistent with the current camera is helpful to control the function of firing bullets from different angles and auxiliary line aiming
bulletSon.transform.rotation = gameObject.transform.rotation;

Track arc part

  • Because the lines drawn by Linerenderer are stuck in some places, which is inconvenient. The lines drawn are flat, so I use prefabricated bodies instead of points to draw the motion track. The trajectory points are calculated by physical formula.
  • Someone may want to throw an object directly and record the track point, which can save the calculation process. In fact, after the object is thrown, it needs time to move, which will bring huge delay. When you move your field of vision a little, you can't get the track until half a day. So it needs to be calculated directly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DrawLineObject : MonoBehaviour
{
    public BulletParameter bullet;
    public GameObject camera;//Get camera
    public GameObject pointObject;//A preform that acts as a guide point
    private GameObject[] points;//Points of guides
    private float speedFront;//Forward speed
    private float forceVertical;//Vertical force

    private float lineTime;//The length of time the line can touch the motion of the bullet
    private int pointNums;//Number of points

    private void Awake()
    {
        speedFront = bullet.speedFront;
        //camera = GameObject.Find("MainCamera");
        forceVertical = bullet.forceVertical;
        lineTime = 0.5f;
        pointNums = 5;
        points = new GameObject[pointNums];
        for(int i = 0; i < pointNums; i++)
        {
            points[i] = Instantiate(pointObject);
        }
    }

    private void Update()
    {
        //Obtain the unit time and calculate the displacement of the point in unit time
        float interval = lineTime / pointNums;

        for (int i = 1; i <= pointNums; i++)
        {
            Vector3 pointNow = camera.transform.position;

            //pointNow = camera.transform.position;

            pointNow += camera.transform.forward * speedFront * interval * i;
            pointNow += camera.transform.up * forceVertical * 0.5f * Mathf.Pow((interval * i), 2);

            points[i - 1].transform.position = pointNow;
        }
    }

}

Direction judgment

  • Summary of ideas:

In case of collision, subtract the coordinates of the bullet and the coordinates of the block to obtain the new coordinates. The axis with the largest absolute value in the new coordinates xyz and its positive and negative can judge the hit surface

  • I first used an enumeration to save the direction
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum Direction
{
    Up=2,
    Down=-2,
    Right=1,
    Left=-1,
    Front=3,
    Back=-3
}

  • The code for judging the direction will not be repeated here.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SideJudge : MonoBehaviour
{

    private void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag == "bullet")
        {
            Vector3 Direct = collision.transform.position - this.transform.position;//Coordinate subtraction
           
            var dir = CollDirection(Direct);//Judgment direction
            print(gameObject.name  + "of" + dir + "Edge, coordinates:" + Direct + "Hit");
        }
    }
    Direction CollDirection(Vector3 direct)
    {
        int index = 0;
        float[] array = new float[] { direct.x, direct.y, direct.z };
        //Judge according to the positive and negative of the maximum axis of the value
        for (int i = 0; i < 3; i++)
        {
            if (Mathf.Abs(direct[i]) > Mathf.Abs(direct[index]))
            {
                index = i;
            }
        }

        return (Direction)( (index + 1) * (int)(direct[index] / Mathf.Abs(direct[index]) ) );
    }
}

Lens movement

Just need a look point, read the mouse state, and then change the position.

Topics: Unity