using System; using DG.Tweening; using System.Collections; using System.Collections.Generic; using UnityEngine; using Random = UnityEngine.Random; public interface IUpdate { public void Update() { } } public abstract class Move { protected List _gos; protected List _setList = new List();//已经设置好坐标的靶子 protected static int RamdomNum = 200; /// /// 是否和已生成的重叠 /// /// /// protected bool CheckOverLap(SpineAnimationLoader target, Vector2 newPos, MoveType movetype = MoveType.Stay, int count = 0) { foreach (var item in _setList) { var distanceMin = item.Radius() + target.Radius(); if (distanceMin >= Vector2.Distance(item.transform.localPosition, newPos)) { //有重叠的 return true; } if (movetype == MoveType.LeftToRight || movetype == MoveType.RightToLeft) { if (distanceMin >= Math.Abs(item.transform.localPosition.y - newPos.y)) { return true; } } else if (movetype == MoveType.RelativeHor)//水平相对运动 { if (count > 2) { //X处于同一方向的话 Y方向不能重叠 if ((item.transform.localPosition.x < 0 && newPos.x < 0) || (item.transform.localPosition.x > 0 && newPos.x > 0)) { if (distanceMin >= Math.Abs(item.transform.localPosition.y - newPos.y)) { return true; } } } else { //只有两个的话 对向也不能重叠 if (distanceMin >= Math.Abs(item.transform.localPosition.y - newPos.y)) { return true; } } } else if (movetype == MoveType.RelativeVet) { if (count > 2) { //Y处于同一方向的话 X方向不能重叠 if ((item.transform.localPosition.y < 0 && newPos.y < 0) || (item.transform.localPosition.y > 0 && newPos.y > 0)) { if (distanceMin >= Math.Abs(item.transform.localPosition.x - newPos.x)) { return true; } } } else { //只有两个的话 对向也不能重叠 if (distanceMin >= Math.Abs(item.transform.localPosition.x - newPos.x)) { return true; } } } } return false; } protected Func IsUIBlock = (SpineAnimationLoader target, Vector2 pos, MoveType moveType, bool log) => { var radius = target.Radius(); var canvasSize = GeneratingTarget.gm.GetCanvasSize(); float halfW = canvasSize.x / 2; float halfH = canvasSize.y / 2; var paddingLeft = Math.Abs(pos.x - radius - (-halfW)); var paddingTop = Math.Abs(halfH - (pos.y + radius)); var paddingRight = Math.Abs(halfW - (pos.x + radius)); var paddingDown = Math.Abs(pos.y - radius - (-halfH)); if (log) Debug.Log($"pos={pos} paddingLeft={paddingLeft} paddingTop={paddingTop} paddingRight={paddingRight} paddingDown={paddingDown}"); //if(moveType == MoveType.Stay || moveType.) //需要对称屏蔽 if (moveType == MoveType.RightToLeft) { //屏蔽整个上方 //上方 if (paddingTop <= 164) return true; //下 右方 if (paddingDown <= 108 && paddingRight <= 134) return true; } else if (moveType == MoveType.LeftToRight) { //上方 左方 if (paddingTop <= 164 && paddingLeft <= 372) return true; //下 右方 if (paddingDown <= 108 && paddingRight <= 134) return true; } else if (moveType == MoveType.RelativeHor) { //屏蔽整个上方 //上方 if (paddingTop <= 164) return true; //下 右方 if (paddingDown <= 108 && paddingRight <= 134) return true; } else if (moveType == MoveType.RelativeVet) { //屏蔽整个左方 //左方 if (paddingLeft <= 372) return true; } else if(moveType == MoveType.Diagonal) { } else { //上方 左方 if (paddingTop <= 164 && paddingLeft <= 372) return true; //下 右方 if (paddingDown <= 108 && paddingRight <= 134) return true; } //左 右 133 if (paddingRight <= 133 || paddingLeft <= 133) return true; return false; }; public void SetGo(List gos) { _setList.Clear(); _gos = gos; InitPos(gos); } public abstract void InitPos(List gos); public int ScreenWidth() { var ScreenWidth = Screen.width; return ScreenWidth; } public int ScreenHeight() { var ScreenHeight = Screen.height; return ScreenHeight; } } /// /// 随机位置静止 /// public class Stay : Move { public override void InitPos(List gos) { float ScaleX(float value) { var width = ScreenWidth(); var scale = 1280f / (float)width; value *= scale; return value; } //随机不重叠的位置 for (int i = 0; i < gos.Count; i++) { var randomPos = gos[i].GetRandomPos(); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.Stay, false) || (CheckOverLap(gos[i], randomPos) && count > 0)) { randomPos = gos[i].GetRandomPos(); count--; if (count <= 0)//找不到就穷举 { var canvasSize = GeneratingTarget.gm.GetCanvasSize(); var HWidth = canvasSize.x * 0.5f; var HHeight = canvasSize.y * 0.5f; var canUse = false; var newPos = Vector2.zero; for (int xPos = 0; xPos <= HWidth * 0.7f; xPos += 20) { for (int yPos = 0; yPos < HHeight * 0.7f; yPos += 15) { newPos.x = xPos; newPos.y = yPos; if (!IsUIBlock(gos[i], newPos, MoveType.Stay, false) && !CheckOverLap(gos[i], newPos)) { canUse = true; break; } newPos.x = xPos; newPos.y = -yPos; if (!IsUIBlock(gos[i], newPos, MoveType.Stay, false) && !CheckOverLap(gos[i], newPos)) { canUse = true; break; } newPos.x = -xPos; newPos.y = yPos; if (!IsUIBlock(gos[i], newPos, MoveType.Stay, false) && !CheckOverLap(gos[i], newPos)) { canUse = true; break; } newPos.x = -xPos; newPos.y = -yPos; if (!IsUIBlock(gos[i], newPos, MoveType.Stay, false) && !CheckOverLap(gos[i], newPos)) { canUse = true; break; } } if (canUse) { randomPos = newPos; break; } } } } // Debug.Log($"i ={i} IsUIBlock={IsUIBlock(gos[i], randomPos, true)} CheckOverLap={CheckOverLap(gos[i], randomPos)} count={count}"); gos[i].SetPos(randomPos); _setList.Add(gos[i]); } } } /// /// 左右水平移动 /// public class LeftToRight : Move, IUpdate { public override void InitPos(List gos) { //随机屏幕左侧位置 for (int i = 0; i < gos.Count; i++) { var randomPos = gos[i].GetRandomPos(PosType.Left); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.LeftToRight, false) || CheckOverLap(gos[i], randomPos, MoveType.LeftToRight) && count > 0) { randomPos = gos[i].GetRandomPos(PosType.Left); count--; } var go = gos[i]; go.SetPos(randomPos); //目标点是横向对称的位置 go.transform.DOLocalMoveX(-go.transform.localPosition.x, go.GetDuration()).SetEase(Ease.InSine); _setList.Add(go); } } } /// /// 右左水平移动 /// public class RightToLeft : Move { public override void InitPos(List gos) { //随机屏幕右侧位置 for (int i = 0; i < gos.Count; i++) { var randomPos = gos[i].GetRandomPos(PosType.Right); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.RightToLeft, false) || CheckOverLap(gos[i], randomPos, MoveType.RightToLeft) && count > 0) { randomPos = gos[i].GetRandomPos(PosType.RightDown); count--; } var go = gos[i]; go.SetPos(randomPos); //目标点是横向对称的位置 go.transform.DOLocalMoveX(-go.transform.localPosition.x, go.GetDuration()).SetEase(Ease.InSine); _setList.Add(go); } } } /// /// 相对水平移动 /// public class RelativeHor : Move { public override void InitPos(List gos) { //随机屏幕左右侧位置 一左一右 for (int i = 0; i < gos.Count; i++) { var tempPos = i % 2 == 0 ? PosType.LeftDown : PosType.RightDown; var randomPos = gos[i].GetRandomPos(tempPos, 0.3f); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.RelativeHor, false) || CheckOverLap(gos[i], randomPos, MoveType.RelativeHor, gos.Count) && count > 0) { randomPos = gos[i].GetRandomPos(tempPos, 0.3f); count--; } var go = gos[i]; go.SetPos(randomPos); //目标点是横向对称的位置 go.transform.DOLocalMoveX(-go.transform.localPosition.x, go.GetDuration()).SetEase(Ease.InSine); _setList.Add(go); } } } /// /// 相对垂直移动 /// public class RelativeVet : Move { public override void InitPos(List gos) { //随机屏幕上下侧位置 一上一下 for (int i = 0; i < gos.Count; i++) { var tempPos = i % 2 == 0 ? PosType.Top : PosType.Down; var randomPos = gos[i].GetRandomPos(tempPos); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.RelativeVet, false) || CheckOverLap(gos[i], randomPos, MoveType.RelativeVet, gos.Count) && count > 0) { randomPos = gos[i].GetRandomPos(tempPos); count--; } var go = gos[i]; go.SetPos(randomPos); //目标点是纵向对称的位置 go.transform.DOLocalMoveY(-go.transform.localPosition.y, go.GetDuration()).SetEase(Ease.InSine); _setList.Add(go); } } } /// /// 同步斜向移动 /// public class Diagonal : Move { public override void InitPos(List gos) { //随机屏幕对角侧位置 一上一下 var random = Random.Range(0, 1); var xRate = 0.25f; var yRate = 0.25f; for (int i = 0; i < gos.Count; i++) { var temp = i % 2 == 0; PosType posType; if (random == 0) posType = temp ? PosType.LeftTop : PosType.LeftDown; else posType = temp ? PosType.RightTop : PosType.RightDown; var randomPos = gos[i].GetRandomPos(posType, xRate, yRate); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.Diagonal, false) && count > 0) { randomPos = gos[i].GetRandomPos(posType, xRate, yRate); count--; } var go = gos[i]; go.SetPos(randomPos); //目标点是对角位置 go.transform.DOLocalMoveY(-go.transform.localPosition.y, go.GetDuration()); go.transform.DOLocalMoveX(-go.transform.localPosition.x, go.GetDuration()); _setList.Add(go); } } } /// /// 同步W型移动 /// public class W : Move { public override void InitPos(List gos) { //从左侧开始 一上一下 往右W轨迹运动 for (int i = 0; i < gos.Count; i++) { var tempPos = i % 2 == 0 ? PosType.LeftTop : PosType.LeftDown; var randomPos = gos[i].GetRandomPos(tempPos, 0.25f, 0.25f); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.W, false) && count > 0) { randomPos = gos[i].GetRandomPos(tempPos, 0.25f, 0.25f); count--; } var go = gos[i]; go.SetPos(randomPos); _setList.Add(go); Vector3[] positions = new Vector3[5]; positions[0] = new Vector3(go.transform.localPosition.x, go.transform.localPosition.y, 0); positions[4] = new Vector3(-positions[0].x, positions[0].y, 0); positions[2] = new Vector3(0, positions[0].y, 0); positions[1] = new Vector3(positions[0].x * 0.5f, -positions[0].y, 0); positions[3] = new Vector3(positions[0].x * -0.5f, -positions[0].y, 0); go.transform.DOLocalPath(positions, go.GetDuration(), PathType.CatmullRom).SetEase(Ease.Linear); } } } /// /// 相对W型移动 /// public class W2 : Move { public override void InitPos(List gos) { List temp = new List(); //四个角落随机创建 W运动 for (int i = 0; i < gos.Count; i++) { if (temp.Count <= 0) { temp.Add(PosType.LeftTop); temp.Add(PosType.LeftDown); temp.Add(PosType.RightDown); temp.Add(PosType.RightTop); } var random = Random.Range(0, temp.Count - 1); var tempPos = temp[random]; temp.RemoveAt(random); var randomPos = gos[i].GetRandomPos(tempPos, 0.25f, 0.25f); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.W2, false) && count > 0) { randomPos = gos[i].GetRandomPos(tempPos, 0.25f, 0.25f); count--; } var go = gos[i]; go.SetPos(randomPos); _setList.Add(go); Vector3[] positions = new Vector3[5]; positions[0] = new Vector3(go.transform.localPosition.x, go.transform.localPosition.y, 0); positions[4] = new Vector3(-positions[0].x, positions[0].y, 0); positions[2] = new Vector3(0, positions[0].y, 0); positions[1] = new Vector3(positions[0].x * 0.5f, -positions[0].y, 0); positions[3] = new Vector3(positions[0].x * -0.5f, -positions[0].y, 0); go.transform.DOLocalPath(positions, go.GetDuration(), PathType.CatmullRom).SetEase(Ease.Linear); } } } /// /// 横排同步水平移动 垂直运动 /// public class HOR : Move { public override void InitPos(List gos) { //随机屏幕上下侧位置 var random = Random.Range(0, 1); var tempPos = random == 0 ? PosType.Top : PosType.Down; for (int i = 0; i < gos.Count; i++) { var randomPos = gos[i].GetRandomPos(tempPos); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.HOR, false) || CheckOverLap(gos[i], randomPos) && count > 0) { randomPos = gos[i].GetRandomPos(tempPos); count--; } var go = gos[i]; go.SetPos(randomPos); //目标点是纵向 go.transform.DOLocalMoveY(-go.transform.localPosition.y, go.GetDuration()); _setList.Add(go); } } } /// /// 垂直同步水平移动 /// public class VET : Move { public override void InitPos(List gos) { //随机屏幕左右侧位置 var random = Random.Range(0, 1); var tempPos = random == 0 ? PosType.Left : PosType.Right; for (int i = 0; i < gos.Count; i++) { var randomPos = gos[i].GetRandomPos(tempPos); int count = RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.VET, false) || CheckOverLap(gos[i], randomPos) && count > 0) { randomPos = gos[i].GetRandomPos(tempPos); count--; } var go = gos[i]; go.SetPos(randomPos); //目标点是横向 go.transform.DOLocalMoveX(-go.transform.localPosition.x, go.GetDuration()); _setList.Add(go); } } } /// /// 旋转移动 /// public class ROT : Move, IUpdate { private float speed; public override void InitPos(List gos) { for (int i = 0; i < gos.Count; i++) { var randomPos = gos[i].GetRandomPos(PosType.Rotate); int count = 2 * RamdomNum; while (IsUIBlock(gos[i], randomPos, MoveType.ROT, false) || CheckOverLap(gos[i], randomPos) && count > 0) { randomPos = gos[i].GetRandomPos(PosType.Rotate); count--; } var go = gos[i]; go.SetPos(randomPos); speed = 360f / go.GetDuration(); _setList.Add(go); } } public void Update() { var center = new Vector3(ScreenWidth() * 0.5f, ScreenHeight() * 0.5f); foreach (var item in _setList) { if (!item.Equals(null)) { var angle = speed * Time.deltaTime; item.rectTransform.Rotate(Vector3.forward, -angle); //center = Camera.main.ScreenToWorldPoint(new Vector3(center.x, center.y, 0)); item.rectTransform.RotateAround(center, Vector3.forward, angle); } } } }