wangguan
2020-12-17 dcbbe82ceca921e73e1789ae87ea8ac6a59c7bff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System;
using ActionGameFramework.Helpers;
using UnityEngine;
 
namespace ActionGameFramework.Projectiles
{
    /// <summary>
    /// Simple IProjectile implementation for a projectile that flies in a straight line, optionally under m_Acceleration.
    /// </summary>
    [RequireComponent(typeof(Rigidbody))]
    public class LinearProjectile : MonoBehaviour, IProjectile
    {
        public float acceleration;
 
        public float startSpeed;
 
        protected bool m_Fired;
 
        protected Rigidbody m_Rigidbody;
 
        public event Action fired;
 
        /// <summary>
        /// Fires this projectile from a designated start point to a designated world coordinate.
        /// </summary>
        /// <param name="startPoint">Start point of the flight.</param>
        /// <param name="targetPoint">Target point to fly to.</param>
        public virtual void FireAtPoint(Vector3 startPoint, Vector3 targetPoint)
        {
            transform.position = startPoint;
 
            Fire(Ballistics.CalculateLinearFireVector(startPoint, targetPoint, startSpeed));
        }
 
        /// <summary>
        /// Fires this projectile in a designated direction.
        /// </summary>
        /// <param name="startPoint">Start point of the flight.</param>
        /// <param name="fireVector">Vector representing direction of flight.</param>
        public virtual void FireInDirection(Vector3 startPoint, Vector3 fireVector)
        {
            transform.position = startPoint;
 
            // If we have no initial speed, we provide a small one to give the launch vector a baseline magnitude.
            if (Math.Abs(startSpeed) < float.Epsilon)
            {
                startSpeed = 0.001f;
            }
 
            Fire(fireVector.normalized * startSpeed);
        }
 
        /// <summary>
        /// Fires this projectile at a designated starting velocity, overriding any starting speeds.
        /// </summary>
        /// <param name="startPoint">Start point of the flight.</param>
        /// <param name="fireVelocity">Vector3 representing launch velocity.</param>
        public void FireAtVelocity(Vector3 startPoint, Vector3 fireVelocity)
        {
            transform.position = startPoint;
 
            startSpeed = fireVelocity.magnitude;
 
            Fire(fireVelocity);
        }
 
        protected virtual void Awake()
        {
            m_Rigidbody = GetComponent<Rigidbody>();
        }
 
        protected virtual void Update()
        {
            if (!m_Fired)
            {
                return;
            }
 
            if (Math.Abs(acceleration) >= float.Epsilon)
            {
                m_Rigidbody.velocity += transform.forward * acceleration * Time.deltaTime;
            }
        }
 
        protected virtual void Fire(Vector3 firingVector)
        {
            m_Fired = true;
 
            transform.rotation = Quaternion.LookRotation(firingVector);
 
            m_Rigidbody.velocity = firingVector;
 
            if (fired != null)
            {
                fired();
            }
        }
    }
}