unity抛物线路径模拟TrajectorySimulation

首先在要模拟的物体上添加PlayerFire脚本

using UnityEngine;

public class PlayerFire : MonoBehaviour
{
    public float fireStrength = 500;
    public Color nextColor = Color.red;
    public Color EndColor = Color.yellow;
}

在任意位置添加TrajectorySimulation脚本

using UnityEngine;

/// <summary>
/// Controls the Laser Sight for the players aim
/// </summary>
public class TrajectorySimulation : MonoBehaviour
{
    // Reference to the LineRenderer we will use to display the simulated path
    public LineRenderer sightLine;

    // Reference to a Component that holds information about fire strengthlocation of cannonetc.
    public PlayerFire playerFire;

    // Number of segments to calculate – more gives a smoother line
    public int segmentCount = 20;

    // Length scale for each segment
    public float segmentScale = 1;

    // gameobject were actually pointing at (may be useful for highlighting a targetetc.)
    private Collider _hitObject;
    public Collider hitObject { get { return _hitObject; } }

    void FixedUpdate()
    {
        simulatePath();
    }

    /// <summary>
    /// Simulate the path of a launched ball.
    /// Slight errors are inherent in the numerical method used.
    /// </summary>
    void simulatePath()
    {
        Vector3[] segments = new Vector3[segmentCount];

        // The first line point is wherever the players cannonetc is
        segments[0] = playerFire.transform.position;

        // The initial velocity
        Vector3 segVelocity = playerFire.transform.up * playerFire.fireStrength * Time.deltaTime;

        // reset our hit object
        _hitObject = null;

        for (int i = 1i < segmentCounti++)
        {
            // Time it takes to traverse one segment of length segScale (careful if velocity is zero)
            float segTime = (segVelocity.sqrMagnitude != 0) ? segmentScale / segVelocity.magnitude : 0;

            // Add velocity from gravity for this segments timestep
            segVelocity = segVelocity + Physics.gravity * segTime;

            // Check to see if were going to hit a physics object
            RaycastHit hit;
            if (Physics.Raycast(segments[i – 1], segVelocityout hitsegmentScale))
            {
                // remember who we hit
                _hitObject = hit.collider;

                // set next position to the position where we hit the physics object
                segments[i] = segments[i – 1] + segVelocity.normalized * hit.distance;
                // correct ending velocitysince we didnt actually travel an entire segment
                segVelocity = segVelocity – Physics.gravity * (segmentScale – hit.distance) / segVelocity.magnitude;
                // flip the velocity to simulate a bounce
                segVelocity = Vector3.Reflect(segVelocityhit.normal);

                /*
                 * Here you could check if the object hit by the Raycast had some property – was 
                 * stickywould cause the ball to explodeor was another ball in the air for 
                 * instanceYou could then end the simulation by setting all further points to 
                 * this last point and then breaking this for loop.
                 */
            }
            // If our raycast hit no objectsthen set the next position to the last one plus v*t
            else
            {
                segments[i] = segments[i – 1] + segVelocity * segTime;
            }
        }

        // At the endapply our simulations to the LineRenderer

        // Set the colour of our path to the colour of the next ball
        Color startColor = playerFire.nextColor;
        Color endColor = playerFire.EndColor;
        //startColor.a = 1;
        //endColor.a = 0;
        sightLine.SetColors(startColorendColor);

        sightLine.SetVertexCount(segmentCount);
        for (int i = 0i < segmentCounti++)
            sightLine.SetPosition(isegments[i]);
    }
}

发布了20 篇原创文章 · 获赞 0 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/gcj2450/article/details/51829621