标签:
先分享一波图,咋们还是看一波图吧。
看完图了之后大家有什么感想,是不是觉得很简单啊,这么简单的游戏还做(感觉逗比刘真的是个逗比了啊,哎 我已经看不下去了)。这个美术很简单,总共就没有几张图。图中的,大家可以先想想一下 如果得到图中的一个圆圈。我们可以从美术哪儿得到啊(这逗比刘 问的啥问题,简直就是个大sb,其实逗比刘也可以画出来啊),大家如果观察仔细的话可以发现大圈和小圈他的那个环的宽度都是一样的,如果用美术得到这样一张图,当我们放大的时候,我们发现这个圈会变大的(但是逗比刘认为这个可以通过shader轻松的解决这个不和谐的问题)。这里我们还是用网格来绘制这样的一个圆环。那么还是从最简单的绘制一个圆环开始吧。第二张图就可以清晰的看到网格,我的思路是这样的。例如我们把一个圆平均分成200份,当然这只是假设,一个小的圆圈怎么可能分成200份呢,所以我们把一个圆的周长按0.2平分即可,首先我们建一个类:
CircleBuilder,
public class CircleBuilder { }当我们不需要继承由monobehavior所得到功能的时候,那么我们就没必要继承monobehavior了,先定义初始化方法:
private Material _shareMaterial; private PlayerHandler _playerHandler; private GameObject _obstacle; private GameObject _circle; public void Intilized(Material mat,PlayerHandler player,GameObject obstacle,GameObject circle) { _shareMaterial = mat; _playerHandler = player; _obstacle = obstacle; _circle = circle; }接下来就开始写主要生成方法:
public GameObject CreateCirlceMesh(float circle,bool isaddColider,ref CircleData circleData) { GameObject ob = new GameObject("Child"); retun ob; }然后我们定义内环和外环顶点数组,然后对其定义
GameObject ob = new GameObject("Child"); List<Vector3> inList = new List<Vector3>(150); List<Vector3> outList = new List<Vector3>(150); Vector3 p1, p2, p3, p4; int nodeCount = (int)((circle * 2 * Mathf.PI) / 0.2f);</span>nodecount表示圆环的节点个数,接着我们开始对2内环数组和外环数组对其赋值。
int nodeCount = (int)((circle * 2 * Mathf.PI) / 0.2f); for (int i = 0; i < nodeCount; i++) { p1=(GetPosByIndex(circle, nodeCount, i)); p2=(GetPosByIndex(circle, nodeCount, (i + 1) % nodeCount)); p3=(GetPosByIndex(circle - 0.1f, nodeCount, (i + 1) % nodeCount)); p4=(GetPosByIndex(circle - 0.1f, nodeCount, i)); if (!outList.Contains(p1)) outList.Add(p1); if (!outList.Contains(p2)) outList.Add(p2); if (!inList.Contains(p4)) inList.Add(p4); if (!inList.Contains(p3)) inList.Add(p3); }内环和外环半径相差0.1,然后根据圆的公式求得圆上各个点。p1,p2外环上相邻的2个点,p3,p4内环上相邻的2个点。最后我们将一个整圆将它分成2个半圆(其实整个圆进行绘制也是可以的)
if (!inList.Contains(p3)) inList.Add(p3); } <span style="background-color: rgb(255, 153, 0);"> int q = inList.Count; int p = q / 2; List<Vector3> lefList=new List<Vector3>(80); List<Vector3> rightList = new List<Vector3>(80); for (int i = 0; i <= p; i++) lefList.Add(inList[i]); for (int i = p; i >=0 ; i--) lefList.Add(outList[i]); for (int i = p; i < q; i++) rightList.Add(inList[i]); rightList.Add(inList[0]); rightList.Add(outList[0]); for (int i = q - 1; i >= p; i--) rightList.Add(outList[i]); CreateChildGameObject(ob.transform,lefList,isaddColider); CreateChildGameObject(ob.transform, rightList, isaddColider); circleData.Intilized(q, ob.transform, _playerHandler.gameObject, circle);</span>
这只是我们做一个环的第一步,我们只有顶点,没有绘制顺序怎么可能绘制出一个圆呢。那么接下来添加CreateChildGameObject方法
<span style="background-color: rgb(255, 153, 0);"> private void CreateChildGameObject(Transform parent, List<Vector3> pointlist, bool isAdd) { GameObject tem = new GameObject("sb"); tem.tag = "Obstacle"; tem.AddComponent<MeshFilter>().mesh = ViewTool.GetObjMesh(pointlist); var meshRenderer = tem.AddComponent<MeshRenderer>(); meshRenderer.sharedMaterial = _shareMaterial; tem.transform.SetParent(parent); if (isAdd) { var colider = tem.AddComponent<PolygonCollider2D>(); colider.points = V3ToV2(pointlist).ToArray(); } } </span>
private Vector3 GetPosByIndex(float circle, int nodecount, int index) { float angle = (360f / nodecount * index - 90) * Mathf.Deg2Rad; float x = Mathf.Cos(angle) * circle; float y = Mathf.Sin(angle) * circle; return new Vector3(x, y, 0); } private List<Vector2> V3ToV2(List<Vector3> points) { List<Vector2> point = new List<Vector2>(); for (int i = 0; i < points.Count; i++) { point.Add(new Vector2(points[i].x, points[i].y)); } return point; }我们还需要添加一个通过点得到网格的方法:GetObjMesh(List<Vector3> pointsList)所以需要贴出这一部分的代码。
public static class ViewTool { public static void ChangeMatColor(Material meshMaterial) { float r = Random.Range(0, 255); float g = Random.Range(0, 255); float b = Random.Range(0, 255); float a = Random.Range(125, 255); Color tempColor=new Color(r/255f,g/255f,b/255f,a/255f); meshMaterial.DOColor(tempColor, 5.0f).OnComplete(delegate { meshMaterial.DOColor(new Color(0,0,0,1), 5.0f); }); } public static void RemoveView(GameObject ob) { for (int i = 0; i < ob.transform.childCount; i++) { var child = ob.transform.GetChild(i); if (child.transform.CompareTag("Spike")) Pools.RecyclePoolObj(child.gameObject); } Object.Destroy(ob); } public static float GetColorLength(Material shareMaterial) { Vector3 temp=new Vector3(1,0,0); Color p = shareMaterial.color; Vector3 endvalue=new Vector3(p.r,p.g,p.b); return Vector3.Dot(endvalue, temp); } public static Mesh GetObjMesh(List<Vector3> pointsList) { Mesh curmesh=new Mesh(); int onepertwo = pointsList.Count/2; List<int> indictInts=new List<int>(); for (int i = 0; i < onepertwo; i++) { indictInts.Add(i); indictInts.Add(2 * onepertwo - 2-i); indictInts.Add(2 * onepertwo - 1-i); indictInts.Add(i); indictInts.Add(i+1); indictInts.Add(2 * onepertwo - 2-i); } curmesh.vertices = pointsList.ToArray(); curmesh.triangles = indictInts.ToArray(); return curmesh; } }一些基本的工作做完之后,我们就可以生成出一个圆了,这里我们的做法其实数据和视图是存在分离的,这里的视图就是我们用网格来生成这个圆环,同样我们也可以用其他的方式,例如直接用一张图。所以还得定义我们的圆环数据类,该数据的包含几个基本的属性,例如圆环的半径,圆环的所在的游戏实例及圆环节点个数及玩家所在的是内环还是外环,所以一个基本的类就构造出来了,玩家需要在环上移动,这个移动方式不是简单的圆周运动,如果是圆周运动的话那么球在大环上我们看起来移动的慢,在小环上移动的慢,这很显然是不和谐的,所以球在圆上做的是直线运动,只不过我们每帧都在指定球的运动的目标点罢了。所以这个基本的类应该具备2个功能就是痛过index索引得到一个在圆上的位置和痛过在圆上的位置得到一个索引。同样还得有一个最基本的方法了。
using System.Collections.Generic; using UnityEngine; public class CircleData { public Transform Parent { set; get; } public ListType CurType { set; get; } public int Count { set; get; } public float Radius { set; get; } public Vector3 NextVector3 { set; get; } public Vector3 PreVector3 { set; get; } private GameObject _player; public Vector3 GetTargetPos(int index,ListType curType) { float offset = _player.GetComponent<CircleCollider2D>().radius; float scale = _player.transform.localScale.x; float r = 0; if (curType == ListType.In) r = Radius - scale * offset-0.1f; if (curType == ListType.Out) r = Radius + scale * offset; return GetTargetPos(r,index); } private Vector3 GetTargetPos(float r,int index) { float x = Mathf.Cos(index * Mathf.PI / Count * 2 - Mathf.PI / 2) * r; float y = Mathf.Sin(index * Mathf.PI / Count * 2 - Mathf.PI / 2) * r; Vector3 temp = new Vector3(x, y, 0); return temp; } public int GetTargetIndex(Vector3 targetVector3,ListType listType) { float offset = _player.GetComponent<CircleCollider2D>().radius; float scale = _player.transform.localScale.x; int min = 0, max = 0; float r=0; if (listType == ListType.In) r = Radius - scale*offset - 0.1f; if (listType == ListType.Out) r = Radius + scale*offset; if (targetVector3.x >= 0 && targetVector3.y >= 0) { min = Count / 4 - 1; max = Count / 4 + 1; } if (targetVector3.x >= 0 && targetVector3.y <= 0) { min = 0; max = Count / 4 + 1; } if (targetVector3.x <= 0 && targetVector3.y >= 0) { min = Count / 2 + 1; max = Count / 4 + 1; } if (targetVector3.x <= 0 && targetVector3.y <= 0) { min = Count / 4 * 3 + 1; max = Count / 4 + 1; } for (int i = 0; i < max; i++) { Vector3 temp = GetTargetPos(r, (i + min) % Count); float distance = Vector3.SqrMagnitude(temp - targetVector3); if (distance < 0.05) return i + min; } return 200; } public void Intilized(int count,Transform parent,GameObject obj,float radius) { CurType=ListType.In; _player = obj; Parent = parent; Radius = radius; Count = count; } }我们还得必须添加几个枚举,要不然程序出报错了。
public enum GameState { None, Playing, Pause, FailOver, } public enum ListType { None, In, Out } public enum LevelState { None, OneState, TwoState, ThreeState, FourState, FiveState, } public enum ColorType { None, Green, Blue, Yellow, Red }这下应该不会出错了,当我们添加一个圆环所具备的基本数据的时候,我们就可以绘制出一个圆环了。如果我们需要绘制出很过个圆并且让这些圆无缝的连接在一起的时候,这时我们需要一个管理者来统一管理。作为一个管理类,他必须具备一些基本的功能例如添加一个圆环实例和删除一个圆环实例。同时还应该有一个基本的初始化方法。所以接着我们需要添加一个管理类了:
public class CirclesManager { private List<CircleData> _circleDatas; private List<GameObject> _circleObjects; private CircleBuilder _circleBuilder; public int Curindex; private PlayerHandler _player; public CircleData CurCircleData { get { return _circleDatas[Curindex]; } } public void Intilized(Material mat, PlayerHandler player, GameObject obstacle,GameObject circle) { Curindex = 0; _circleDatas=new List<CircleData>(); _circleObjects=new List<GameObject>(4); for (int i = 0; i < 4; i++) { var temp=new CircleData(); _circleDatas.Add(temp); } _player = player; _circleBuilder=new CircleBuilder(); _circleBuilder.Intilized(mat, player, obstacle, circle); } public void InitlizedCircleObj(int totalNum,List<float> circleList) { for (int i = 0; i < totalNum; i++) { var circleData = _circleDatas[i]; GameObject ob = _circleBuilder.CreateCirlceMesh(circleList[i], false,ref circleData); _circleObjects.Add(ob); if (i==0) ob.transform.position = new Vector3(0, 0, 0); else { float radius = _circleDatas[i].Radius + _circleDatas[i-1].Radius - 0.1f; ob.transform.position = VectorHelpr.GetVector3ByDis(radius, _circleDatas[i - 1].Parent.position); Vector3 dir = (ob.transform.position - _circleDatas[i - 1].Parent.position).normalized; _circleDatas[i - 1].NextVector3 = dir * (_circleDatas[i - 1].Radius - 0.1f - _player.Skin)+ _circleDatas[i - 1].Parent.position; _circleDatas[i].PreVector3 = -dir * (_circleDatas[i].Radius - _player.Skin - 0.1f) + _circleDatas[i].Parent.position; } } } private void AddCirlceToList(int num) { int count = _circleDatas.Count; var preCircleData = _circleDatas[Curindex]; GameObject ob1 = _circleBuilder.CreateCirlceMesh(UnityEngine.Random.Range(1.5f, 2.7f), false, ref preCircleData); int temp = Curindex; Curindex++; Curindex %= 4; var curCircleData = _circleDatas[(Curindex + 2) % count]; float radius = curCircleData.Radius + preCircleData.Radius - 0.1f; ob1.transform.position = VectorHelpr.GetVector3ByDis(radius, curCircleData.Parent.position); Vector3 dir = (preCircleData.Parent.position - curCircleData.Parent.position).normalized; curCircleData.NextVector3 = dir * (curCircleData.Radius - 0.1f - _player.Skin) + curCircleData.Parent.position; preCircleData.PreVector3 = -dir * (preCircleData.Radius - _player.Skin - 0.1f) + preCircleData.Parent.position; _circleObjects[temp] = ob1; _circleBuilder.AddObsToCircle(_circleDatas[(temp + 2) % count], num); } public void UpdateList(int num) { ViewTool.RemoveView(_circleObjects[Curindex]); _circleObjects[Curindex]=null; AddCirlceToList(num); } public void ClearCircleData() { _circleDatas.Clear(); for (int i = 0; i < _circleObjects.Count; i++) { Object.Destroy(_circleObjects[i]); } } public void Reintilized(Action callAction) { bool isComplete = false; for (int i = 0; i < _circleObjects.Count; i++) { _circleObjects[i].transform.localScale = Vector3.zero; _circleObjects[i].transform.DOScale(new Vector3(1, 1, 0), 1.0f).OnComplete(delegate { if (!isComplete) { isComplete = true; callAction.Invoke(); } }); } } }管理类就只有添加,删除,因为删除和添加是一个前一个后进行的,所以我用一个UpdateList(int num)代替就行了,其他的都是基本初始化方法了。当我们游戏开始的时候,我们需要生成几个相连接的圆环,所以他应该还要定义一个方法就是初始化我们最开始游戏运行时的圆环数据和圆环实例。管理类需要用到几个工具方法。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using DG.Tweening; using UnityEngine; public static class VectorHelpr { public static Vector3 GetVector3ByDis(float radius,Vector3 pos) { float x = UnityEngine.Random.Range(radius/3, 2*radius/3); float y = -Mathf.Sqrt(radius*radius-x*x); if (pos.x > 0) x = -x; return pos+ new Vector3(x,y,0); } public static bool JudgeGameOver(CircleData curCircleData,Transform player) { int cur = curCircleData.GetTargetIndex(curCircleData.NextVector3-curCircleData.Parent.position,ListType.In); int nextindex = curCircleData.GetTargetIndex(player.position - curCircleData.Parent.position,ListType.Out); ListType curType = curCircleData.CurType; if (curType == ListType.Out) { bool b1 = Mathf.Abs(nextindex - cur) <=3; return b1; } return false; } public static void CamerFloow(Camera mainCamera,Vector3 targetVector3) { targetVector3 = new Vector3(targetVector3.x, targetVector3.y, mainCamera.transform.position.z); mainCamera.transform.position = targetVector3; } public static Vector3 GetNormalDir(Vector3 dir, Vector3 center) { Vector3 endvalue = Quaternion.AngleAxis(90, new Vector3(0, 0, 1))*dir; return endvalue; } public static float GetSpeedByLevel(SpeedLevel curLevel) { switch (curLevel) { case SpeedLevel.One: return 2f; case SpeedLevel.Two: return 2.5f; case SpeedLevel.Three: return 3f; case SpeedLevel.Four: return 4; case SpeedLevel.Five: return 4.5f; } return 0; } private static LevelState GetLevelStateByScore(int score) { if (score >= 0 && score <= 50) return LevelState.OneState; if(score>50&&score<=150) return LevelState.TwoState; if(score>150&&score<=300) return LevelState.ThreeState; if(score>300&&score<=500) return LevelState.FourState; if(score>500&&score<=700) return LevelState.FiveState; return LevelState.None; } public static Vector2 GetSpeedAndObsByScore(int score) { LevelState curLevelState = GetLevelStateByScore(score); float speed=0, num=0; switch (curLevelState) { case LevelState.OneState: speed = GetSpeedByLevel(SpeedLevel.One); num = UnityEngine.Random.Range(0, 10)%6 == 0 ? 0 : UnityEngine.Random.Range(2,5); break; case LevelState.TwoState: speed = GetSpeedByLevel(SpeedLevel.One); int min = UnityEngine.Random.Range(2, 4); num = UnityEngine.Random.Range(0, 10) % 6 == 0 ? min : min + 2; break; case LevelState.ThreeState: speed = GetSpeedByLevel(SpeedLevel.Two); num = UnityEngine.Random.Range(4, 6); break; case LevelState.FourState: speed = GetSpeedByLevel(SpeedLevel.Three); num = UnityEngine.Random.Range(4, 6)+1; break; case LevelState.FiveState: speed = GetSpeedByLevel(SpeedLevel.Four); num = UnityEngine.Random.Range(4, 7)+2; break; } return new Vector2(speed, num); } public static bool IsBoundIndex(int minindex,int maxindex,int index) { bool b1 = Mathf.Abs(index - minindex) > 4; bool b2 = Mathf.Abs(index - maxindex) > 4; return (b1 && b2); } public static List<int> GetRandomInts(int min,int max,int num) { List<int> endvalue=new List<int>(); while (num>=1) { int temp = UnityEngine.Random.Range(min, max); if (!endvalue.Contains(temp)) { endvalue.Add(temp); num--; } } return endvalue; } public static Vector3 GetPosByNormal(Vector3 start,Vector3 end,Vector3 temp,float pradius,float nradius) { Vector3 dir = (end - start).normalized; Vector3 dir1 = (temp - start).normalized; float cos = Vector3.Dot(dir, dir1); float sin = Mathf.Sqrt(1 - cos * cos); bool b = (dir.x*dir1.y - dir.y*dir1.x)>0; Vector3 normal = (Quaternion.Euler(0, 0, 90) * dir).normalized; float vdistance = pradius*sin; float hdistance =Mathf.Sqrt(nradius*nradius - vdistance*vdistance); Vector3 endvalue = -dir*hdistance + (b?1:-1)*normal*vdistance; return endvalue+end; } }工具类中的每个方法都很容易理解,我就不多讲,看方法的名字就知道方法是干什么的了。所以我们写代码的时候方法名字和方法体里面要干的事最好保持一致,这样才能让别人和自己以后回顾代码的时候更容易快速的理解。因为你的代码是写个人看的不是写个机器看的,如果你的一个类动不动就是上千行,那么阅读起来会是相当困难的。接下来就讲一下我们的主游戏逻辑类该怎么去写,首先我们的明白一个道理,应该尽量保证我们建的类在不需要继承monobehavior所带来的好处的时候那么我们就没必要去继承至于为什么我前面代码优化中讲到这点。所以我们主游戏逻辑类应该继承monobehavior,主要是因为我们需要在inspect面板上指定一些预设和ui。这个主游戏逻辑相当于值最高层的管理类,所以它的级别应该比较高了,所以常用的调用关系应该是它去调用别人而不是别人可以调用它,如果存在这方面的调用,例如主游戏逻辑中管理游戏的状态,假如我们的玩家死了的话。我们需要指定游戏结束,这里我们几种方法分别列举一下:1 我们可以用一种消息处理机制(这部分前面已经讲到) 2 我们可以使用接口,让主游戏逻辑类继承一个改变游戏状态的接口,然后我们在玩家类持有该接口的引用,同时我们在主游戏逻辑类中初始化玩家的时候给指定引用例如intilized(this)。3 最后一种方法就是单例了。我个人建议不采用,前面2种方法任选其一即可。好了贴出主游戏逻辑的代码吧
using System; using UnityEngine; using System.Collections; using System.Collections.Generic; using DG.Tweening; using UnityEngine.EventSystems; using UnityEngine.UI; using Random = UnityEngine.Random; public class GameLayer : MonoBehaviour, IGetCurGameState { [SerializeField] private Material _meshMaterial; [SerializeField] private GameObject _obstacle; [SerializeField] private GameObject _explostion; [SerializeField] private Camera _mainCamera; [SerializeField] private GameObject _playerprefab; [SerializeField] private EventSystem eventSystem; [SerializeField] private GraphicRaycaster graphicRaycaster; [SerializeField] private PlayerHandler _playerHandler; [SerializeField] private UIManager _uiManager; [SerializeField] private GameObject _circle; private float _speed; private GameState _curGameState; private int _score = 0; private CirclesManager _manager; private bool _isReverse=true; #region MonoBehavior Function private PointerEventData _eventData=null; private void Awake() { _eventData = new PointerEventData(eventSystem); } private void Start() { _curGameState = GameState.Playing; _manager=new CirclesManager(); _manager.Intilized(_meshMaterial, _playerHandler, _obstacle, _circle); _manager.InitlizedCircleObj(4, new List<float>() { 2, 1.5f, 2.5f, 1.0f }); _uiManager.Intilized(this); _uiManager.AddListenerToButton(); MessagingSystem.Instance.AttachListener(typeof(GamstateMessage), this.HandleGameStateMsg); _mainCamera.transform.DOMove(new Vector3(0, 0, -10), 2.0f); _speed = (int)VectorHelpr.GetSpeedAndObsByScore(_score).x; Pools.ManageRecyclePool(new ObjectPool() { Prefab = _obstacle, InstancesToPreallocate = 15}); } private Vector3 _offsetVector3; private bool _isMove = false; private CircleData _curCircleData; private float _tempr; private bool _isDown = false; private void Update() { if (_curGameState == GameState.Playing) { _curCircleData = _manager.CurCircleData; if (Input.GetMouseButtonDown(0)&&_isDown) { if (CheckGuiRaycastObjects()) return; var temp = _curCircleData.GetTargetIndex(_curCircleData.NextVector3 - _curCircleData.Parent.position, ListType.In); var temp1 = _curCircleData.GetTargetIndex(_playerHandler.transform.position - _curCircleData.Parent.position, ListType.In); if (Mathf.Abs(temp - temp1) <= 1) { Vector3 prePos = _curCircleData.Parent.position; float radiu = _curCircleData.Radius; _speed = (int) VectorHelpr.GetSpeedAndObsByScore(_score).x; _manager.UpdateList((int)VectorHelpr.GetSpeedAndObsByScore(_score).y); _isReverse = !_isReverse; _curCircleData = _manager.CurCircleData; var endvalue = VectorHelpr.GetPosByNormal(prePos, _curCircleData.Parent.position, _playerHandler.transform.position, radiu- 0.2f, _curCircleData.Radius - 0.2f); _index = _curCircleData.GetTargetIndex(endvalue - _curCircleData.Parent.position, ListType.In); if (_isReverse) { _index++; _index %= _curCircleData.Count; } else { _index--; if (_index < 0) _index += _curCircleData.Count; } _playerHandler.transform.position = endvalue; _isMove = false; _curCircleData.CurType = ListType.In; VectorHelpr.CamerFloow(_mainCamera, _curCircleData.Parent.position); _uiManager.SetCurScoreText(++_score); } else { if (_curCircleData.CurType == ListType.In) { _curCircleData.CurType = ListType.Out; _offsetVector3 = _playerHandler.transform.position - _curCircleData.Parent.position; _tempr = _curCircleData.Radius + _playerHandler.Skin; _playerHandler.transform.position = _curCircleData.Parent.position + _offsetVector3.normalized * _tempr; } else { _offsetVector3 = _playerHandler.transform.position - _curCircleData.Parent.position; _tempr = _curCircleData.Radius - _playerHandler.Skin - 0.1f; _playerHandler.transform.position = _curCircleData.Parent.position + _offsetVector3.normalized * _tempr; _curCircleData.CurType = ListType.In; } } } if (_index > 0 && !_isDown) _isDown = true; if (_isMove) MoveThisPlayer(_curCircleData); _isMove = true; if (VectorHelpr.JudgeGameOver(_curCircleData, _playerHandler.transform)) _curGameState = GameState.FailOver; } if (_curGameState == GameState.FailOver) { Instantiate(_explostion, _playerHandler.transform.position, Quaternion.identity); Destroy(_playerHandler.gameObject); _uiManager.PopUpFailItem(0, null); _manager.ClearCircleData(); _curGameState = GameState.None; } } #endregion #region Private Function private int _index = 0; private void MoveThisPlayer(CircleData curCircleData) { Vector3 targetPos = curCircleData.GetTargetPos(_index, curCircleData.CurType) + curCircleData.Parent.position; Vector3 playerPos = _playerHandler.transform.position; float delta = _speed*Time.smoothDeltaTime; bool b = (Vector3.SqrMagnitude(targetPos - playerPos) < delta*delta); if (b) { if (_isReverse) { _index++; _index %= curCircleData.Count; } else { _index--; if (_index < 0) _index += curCircleData.Count; } } _playerHandler.transform.position += delta * (targetPos - playerPos).normalized; } private bool HandleGameStateMsg(BaseMessage curMessage) { GamstateMessage gamstateMessage = curMessage as GamstateMessage; if (gamstateMessage != null) { _curGameState = gamstateMessage.CurGameState; } return true; } private bool CheckGuiRaycastObjects() { _eventData.pressPosition = Input.mousePosition; _eventData.position = Input.mousePosition; List<RaycastResult> list = new List<RaycastResult>(); graphicRaycaster.Raycast(_eventData, list); for (int i = 0; i < list.Count; i++) { if (list[i].gameObject.CompareTag("Button")) return true; } return false; } #endregion public GameState GetGameState() { return _curGameState; } public void ReIntilized() { GameObject ob = GameObject.Instantiate(_playerprefab, new Vector3(0,0.5f,0), Quaternion.identity)as GameObject; if (ob != null) _playerHandler = ob.GetComponent<PlayerHandler>(); _speed =VectorHelpr.GetSpeedByLevel(SpeedLevel.One); _manager.Intilized(_meshMaterial, _playerHandler, _obstacle, _circle); _manager.InitlizedCircleObj(4, new List<float>() { 2, 1.5f, 2.5f, 1.0f }); _manager.Reintilized(delegate {_curGameState=GameState.Playing;}); _isReverse = true; _score = 0; _index = 0; _mainCamera.transform.position=new Vector3(0,0,-10); VectorHelpr.CamerFloow(_mainCamera, _manager.CurCircleData.Parent.position); } }方法体里面的东西比较简单没人什么复杂,就前面圆圈的生成麻烦一点了。如果还有什么不懂的可以qq和我讨论:1850761495
http://pan.baidu.com/s/1i5uHuXf
标签:
原文地址:http://blog.csdn.net/u012565990/article/details/51921305