
1.制作障碍系统 (1.制作几种类型的障碍物的预制体 ((*.编写障碍物基类,以下几种均继承自基类,含碰撞体,RememberY(生成障碍物时该有多大的Y) ((1.矮障碍,仅碰撞体 ((2.高障碍,仅碰撞体 ((3.可冲破障碍 (((1.除基本碰撞体外,额外包含一个触发器,比碰撞体先检测到马,同时获取马的x速度,大于阈值则给障碍做破碎,用马的力度决定破碎力,关闭碎块和马的碰撞 (((*.导入某2D破碎插件 ((4.人马分离障碍 (((WAIT,需要等待人马分离系统先搭建 (2.编写障碍物生成系统 ((1.每若干时间,生成一个随机一种障碍,若干的范围可控 (((1.设计协程,从预制体列表中随机出一种,并在计算好的位置实例化,随后等待范围内的若干时间,然后检查马的存活情况,若马仍存活,重新调用本协程 ((2.生成的位置:x在相机右侧若干不变距离,y根据障碍物的不同而不同,需要计算保存。 (3.编写障碍物消亡系统 ((1.每个障碍物和碎片都会在离开镜头后被删除
178 lines
5.2 KiB
C#
178 lines
5.2 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
|
|
[RequireComponent(typeof(Rigidbody2D))]
|
|
public class Explodable : MonoBehaviour
|
|
{
|
|
public System.Action<List<GameObject>> OnFragmentsGenerated;
|
|
|
|
public bool allowRuntimeFragmentation = false;
|
|
public int extraPoints = 0;
|
|
public int subshatterSteps = 0;
|
|
|
|
public string fragmentLayer = "Default";
|
|
public string sortingLayerName = "Default";
|
|
public int orderInLayer = 0;
|
|
|
|
public enum ShatterType
|
|
{
|
|
Triangle,
|
|
Voronoi
|
|
};
|
|
public ShatterType shatterType;
|
|
public List<GameObject> fragments = new List<GameObject>();
|
|
private List<List<Vector2>> polygons = new List<List<Vector2>>();
|
|
|
|
/// <summary>
|
|
/// Creates fragments if necessary and destroys original gameobject
|
|
/// </summary>
|
|
public void explode()
|
|
{
|
|
//if fragments were not created before runtime then create them now
|
|
if (fragments.Count == 0 && allowRuntimeFragmentation)
|
|
{
|
|
generateFragments();
|
|
}
|
|
//otherwise unparent and activate them
|
|
else
|
|
{
|
|
foreach (GameObject frag in fragments)
|
|
{
|
|
frag.transform.parent = null;
|
|
frag.SetActive(true);
|
|
}
|
|
}
|
|
//if fragments exist destroy the original
|
|
if (fragments.Count > 0)
|
|
{
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Creates fragments and then disables them
|
|
/// </summary>
|
|
public void fragmentInEditor()
|
|
{
|
|
if (fragments.Count > 0)
|
|
{
|
|
deleteFragments();
|
|
}
|
|
generateFragments();
|
|
setPolygonsForDrawing();
|
|
foreach (GameObject frag in fragments)
|
|
{
|
|
frag.transform.parent = transform;
|
|
frag.SetActive(false);
|
|
}
|
|
}
|
|
public void deleteFragments()
|
|
{
|
|
foreach (GameObject frag in fragments)
|
|
{
|
|
if (Application.isEditor)
|
|
{
|
|
DestroyImmediate(frag);
|
|
}
|
|
else
|
|
{
|
|
Destroy(frag);
|
|
}
|
|
}
|
|
fragments.Clear();
|
|
polygons.Clear();
|
|
}
|
|
/// <summary>
|
|
/// Turns Gameobject into multiple fragments
|
|
/// </summary>
|
|
private void generateFragments()
|
|
{
|
|
fragments = new List<GameObject>();
|
|
switch (shatterType)
|
|
{
|
|
case ShatterType.Triangle:
|
|
fragments = SpriteExploder.GenerateTriangularPieces(gameObject, extraPoints, subshatterSteps);
|
|
break;
|
|
case ShatterType.Voronoi:
|
|
fragments = SpriteExploder.GenerateVoronoiPieces(gameObject, extraPoints, subshatterSteps);
|
|
break;
|
|
default:
|
|
Debug.Log("invalid choice");
|
|
break;
|
|
}
|
|
//sets additional aspects of the fragments
|
|
foreach (GameObject p in fragments)
|
|
{
|
|
if (p != null)
|
|
{
|
|
p.layer = LayerMask.NameToLayer(fragmentLayer);
|
|
p.GetComponent<Renderer>().sortingLayerName = sortingLayerName;
|
|
p.GetComponent<Renderer>().sortingOrder = orderInLayer;
|
|
}
|
|
}
|
|
|
|
foreach (ExplodableAddon addon in GetComponents<ExplodableAddon>())
|
|
{
|
|
if (addon.enabled)
|
|
{
|
|
addon.OnFragmentsGenerated(fragments);
|
|
}
|
|
}
|
|
}
|
|
private void setPolygonsForDrawing()
|
|
{
|
|
polygons.Clear();
|
|
List<Vector2> polygon;
|
|
|
|
foreach (GameObject frag in fragments)
|
|
{
|
|
polygon = new List<Vector2>();
|
|
foreach (Vector2 point in frag.GetComponent<PolygonCollider2D>().points)
|
|
{
|
|
Vector2 offset = rotateAroundPivot((Vector2)frag.transform.position, (Vector2)transform.position, Quaternion.Inverse(transform.rotation)) - (Vector2)transform.position;
|
|
offset.x /= transform.localScale.x;
|
|
offset.y /= transform.localScale.y;
|
|
polygon.Add(point + offset);
|
|
}
|
|
polygons.Add(polygon);
|
|
}
|
|
}
|
|
private Vector2 rotateAroundPivot(Vector2 point, Vector2 pivot, Quaternion angle)
|
|
{
|
|
Vector2 dir = point - pivot;
|
|
dir = angle * dir;
|
|
point = dir + pivot;
|
|
return point;
|
|
}
|
|
|
|
void OnDrawGizmos()
|
|
{
|
|
if (Application.isEditor)
|
|
{
|
|
if (polygons.Count == 0 && fragments.Count != 0)
|
|
{
|
|
setPolygonsForDrawing();
|
|
}
|
|
|
|
Gizmos.color = Color.blue;
|
|
Gizmos.matrix = transform.localToWorldMatrix;
|
|
Vector2 offset = (Vector2)transform.position * 0;
|
|
foreach (List<Vector2> polygon in polygons)
|
|
{
|
|
for (int i = 0; i < polygon.Count; i++)
|
|
{
|
|
if (i + 1 == polygon.Count)
|
|
{
|
|
Gizmos.DrawLine(polygon[i] + offset, polygon[0] + offset);
|
|
}
|
|
else
|
|
{
|
|
Gizmos.DrawLine(polygon[i] + offset, polygon[i + 1] + offset);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|