summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Projectile/Projectile.cs
blob: a6411f5f1016cc7bda0e7cc90bb4a30cf932a63b (plain)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public struct ProjectileInfo
{
    public UnitController owner;
    public Vector3 position;
    public Vector3 rotation;
    public Vector3 scale;
    public Vector3 direction;
    public Vector3 velocity;
    public bool towardDirection;
    public float lifetime;
    public bool useGravity; 
    public float gravity;
    public string sparkPath;
}

public class Projectile : MonoBehaviour
{
    public enum EBoxType
    {
        Single = 0,
        Multiple = 1, 
        Grid = 2,
    }

    #region 序列化数据
    public EBoxType type;

    public Box collider;

	public List<Box> colliders;

    public Box colliderGrid;
    public Vector3 slice;
    #endregion 

    [HideInInspector]
    public UnitController owner;

    [HideInInspector]
    public bool isActive;

    [HideInInspector]
    public Vector3 velocity; // 初始速度

    [HideInInspector]
    public float gravity;

    [HideInInspector]
    public bool towardDirection; // foward朝向运动的方向

    [HideInInspector]
    public float lifetime;

    public string sparkPath;

    private List<int> m_Hitmask;

    public float time;

    private bool markDestroy;

    public void Initialize(ProjectileInfo info)
    {
        this.owner = info.owner;
        this.transform.rotation = Quaternion.Euler(info.rotation);
        this.transform.position = info.position;
        this.transform.localScale.Scale(info.scale);
        this.velocity = info.velocity;
        this.lifetime = info.lifetime;
        this.sparkPath = info.sparkPath;

        markDestroy = false;

        time = 0;

        m_Hitmask = new List<int>();
    }

    void OnEnable()
	{
		ColliderRegistry.Instance.AddProjectile(this);	
	}

    public void Update()
    {
        Update(Time.deltaTime);
    }

    public void Update(float deltaTime)
    {
        this.transform.position += this.velocity * deltaTime;
        time += deltaTime;
        if (time > this.lifetime || markDestroy)
        {
            DestroyImmediate(this.gameObject);
        }
    }

    void OnDestroy()
	{
		ColliderRegistry.Instance.RemoveProjectile(this);
	}

    public IEnumerable GetCollidersInWorldSpace()
    {
        if(type == EBoxType.Single)
        {
            Box box = collider;
            box.center = transform.position + collider.center;
            yield return box; 
        }
        else if(type == EBoxType.Multiple)
        {
            for(int i = 0; i < colliders.Count; ++i)
            {
                Box box = colliders[i];
                box.center = transform.position + box.center;
                yield return box;
            }
        }
        else if(type == EBoxType.Grid)
        {
            Vector3 lowerCornor = colliderGrid.center - colliderGrid.size / 2;
            Vector3 cellSize = Vector3.Scale(colliderGrid.size, new Vector3(1f / slice.x, 1f / slice.y, 1f / slice.z));
            for (int x = 0; x < slice.x; ++x)
            {
                for(int y = 0; y < slice.y; ++y)
                {
                    for(int z = 0; z < slice.z; ++z)
                    {
                        Vector3 xyz = new Vector3(x, y, z);
                        Box box = new Box();
                        box.size = cellSize;
                        box.center = lowerCornor + transform.position + Vector3.Scale(cellSize, xyz) + Vector3.Scale(cellSize, new Vector3(0.5f, 0.5f, 0.5f));
                        yield return box;
                    }
                }
            }
        }
        yield break;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red * 0.5f;
        foreach(var itor in GetCollidersInWorldSpace())
        {
            Box box = (Box)itor;
            Gizmos.DrawCube(box.center, box.size);
        }
    }

    public bool CanHit(int target)
    {
        return !m_Hitmask.Contains(target);
    }

    public void RecordTarget(int targethash)
    {
        m_Hitmask.Add(targethash);
    }

    public void OnShot(CollisionInfo collision)
    {
        GameObject spark = ResourceManager.Instance.LoadAsset<GameObject>(sparkPath);
        if (spark)
        {
            GameObject obj = GameObject.Instantiate(spark);
#if UNITY_EDITOR
            obj.transform.SetParent(TimelineEventProxy.Root_Particles.transform);
#endif
            obj.transform.position = collision.collidee.unitCollider.owner.center;

            markDestroy = true;
        }
    }

}