Road Crossing Game Template 学习
using UnityEngine; using System; namespace RoadCrossing.Types { /// <summary> /// 小路 /// </summary> [Serializable] public class Lane { /// <summary> /// 小路相关的游戏物体 /// </summary> public Transform laneObject; /// <summary> /// 生成这条路的几率 /// </summary> ; /// <summary> /// 小路的宽度 /// </summary> ; /// <summary> /// 生成物品的几率 /// </summary> ; } }
Lane
using UnityEngine; using System; namespace RoadCrossing.Types { /// <summary> /// 掉落物品 /// </summary> [Serializable] public class ObjectDrop { /// <summary> /// 掉落物品 /// </summary> public Transform droppedObject; /// <summary> /// 掉落几率 /// </summary> ; } }
ObjectDrop
using UnityEngine; using System; namespace RoadCrossing.Types { /// <summary> /// 商店道具 /// </summary> [Serializable] public class ShopItem { /// <summary> /// 这个道具关联的按钮 /// </summary> public Transform itemButton; /// <summary> /// 解锁状态,0 未解锁 1 已解锁 /// </summary> ; /// <summary> /// 解锁这个道具的花费 /// </summary> ; /// <summary> /// 这个道具在存档中的键名 /// </summary> public string playerPrefsName = "FroggyUnlock"; } }
ShopItem
using System; namespace RoadCrossing.Types { /// <summary> /// 接触后调用的函数信息 /// </summary> [Serializable] public class TouchFunction { /// <summary> /// 调用的函数名称 /// </summary> public string functionName = "CancelMove"; /// <summary> /// 在哪个目标上调用函数 /// </summary> public string targetTag = "Player"; /// <summary> /// 传递给函数的参数 /// </summary> ; } }
TouchFunction
using UnityEngine; using RoadCrossing.Types; namespace RoadCrossing { /// <summary> /// 能与玩家交互的块,可以是岩石,墙,敌人,金币 /// </summary> public class RCGBlock : MonoBehaviour { /// <summary> /// 能够接触这个块的物体的标签 /// </summary> public string touchTargetTag = "Player"; /// <summary> /// 这个块被目标接触后调用的函数列表 /// </summary> public TouchFunction[] touchFunctions; /// <summary> /// 经过多少次接触后删除这个物体 /// </summary> ; /// <summary> /// 这个物体是否可以被移除 /// </summary> internal bool isRemovable = false; /// <summary> /// 当这个物体被接触后的动画剪辑 /// </summary> public AnimationClip hitAnimation; /// <summary> /// 当这个物体被接触后的声音剪辑 /// </summary> public AudioClip soundHit; /// <summary> /// AudioSource所属物体的标签 /// </summary> public string soundSourceTag = "GameController"; /// <summary> /// 物体死亡后创建的死亡的特效 /// </summary> public Transform deathEffect; void Start() { ) isRemovable = true; } void OnTriggerEnter(Collider other) { if( other.tag == touchTargetTag ) { //调用目标物体上的函数 foreach( var touchFunction in touchFunctions ) { if( touchFunction.targetTag != string.Empty && touchFunction.functionName != string.Empty ) { GameObject.FindGameObjectWithTag(touchFunction.targetTag).SendMessage(touchFunction.functionName, touchFunction.functionParameter); } } //满足条件,播放动画 if( GetComponent<Animation>() && hitAnimation ) { GetComponent<Animation>().Stop(); GetComponent<Animation>().Play(hitAnimation.name); } //满足条件,删除物体,创建死亡特效 if( isRemovable == true ) { removeAfterTouches--; ) { if( deathEffect ) Instantiate(deathEffect, transform.position, Quaternion.identity); Destroy(gameObject); } } //满足条件,播放声音 if( soundSourceTag != string.Empty && soundHit ) GameObject.FindGameObjectWithTag(soundSourceTag).GetComponent<AudioSource>().PlayOneShot(soundHit); } } } }
RCGBlock
using UnityEngine; namespace RoadCrossing { /// <summary> /// 控制上下左右点击的按钮(collider) /// </summary> public class RCGButtonFunction : MonoBehaviour { /// <summary> /// 要执行函数的物体 /// </summary> public Transform functionTarget; /// <summary> /// 要执行的函数名称 /// </summary> public string functionName; /// <summary> /// 传递给函数的参数 /// </summary> public string functionParameter; /// <summary> /// 点击声音 /// </summary> public AudioClip soundClick; /// <summary> /// AudioSource 所属的物体 /// </summary> public Transform soundSource; void OnMouseDrag() { ExecuteFunction(); } /// <summary> /// 执行函数 /// </summary> void ExecuteFunction() { if( soundSource ) if( soundSource.GetComponent<AudioSource>() ) soundSource.GetComponent<AudioSource>().PlayOneShot(soundClick); if( functionName != string.Empty ) { if( functionTarget ) { functionTarget.SendMessage(functionName, functionParameter); } } } } }
RCGButtonFunction
using System.Collections; using UnityEngine; using UnityEngine.UI; using RoadCrossing.Types; namespace RoadCrossing { /// <summary> /// 游戏控制 /// </summary> public class RCGGameController : MonoBehaviour { /// <summary> /// 玩家物体列表 /// </summary> public Transform[] playerObjects; /// <summary> /// 当前玩家物体索引 /// </summary> public int currentPlayer; /// <summary> /// 跟随玩家的相机 /// </summary> public Transform cameraObject; /// <summary> /// 控制玩家移动的按钮(collider),如果是滑动控制,这些物体会被禁用 /// </summary> public Transform moveButtonsObject; /// <summary> /// 是否使用滑动控制 /// </summary> public bool swipeControls = false; /// <summary> /// 滑动起点 /// </summary> internal Vector3 swipeStart; /// <summary> /// 滑动终点 /// </summary> internal Vector3 swipeEnd; ; /// <summary> /// 滑动命令取消前的等待时间 /// </summary> ; /// <summary> /// /// </summary> internal float swipeTimeoutCount; /// <summary> /// 所有的小路预设列表 /// </summary> public Lane[] lanes; internal Lane[] lanesList; public ObjectDrop[] objectDrops; internal Transform[] objectDropList; ; /// <summary> /// 游戏开始前与预创建的小路数量 /// </summary> ; /// <summary> /// 下一条小路的位置 /// </summary> ; /// <summary> /// 得分 /// </summary> ; /// <summary> /// 显示得分的文本 /// </summary> public Transform scoreText; /// <summary> /// 最高分数 /// </summary> ; /// <summary> /// 游戏中总共获得的分数 /// </summary> public string coinsPlayerPrefs = "Coins"; /// <summary> /// 游戏速度 /// </summary> ; /// <summary> /// 玩家升级需要的点数 /// </summary> ; /// <summary> /// 增加的分数 /// </summary> ; /// <summary> /// 在玩家身后追逐玩家的物体 /// </summary> public Transform deathLineObject; /// <summary> /// 追杀物体的移动速度 /// </summary> ; /// <summary> /// 追杀物体每次增加的速度的值 /// </summary> ; /// <summary> /// 追杀物体的最大移动速度 /// </summary> public float deathLineSpeedMax = 1.5f; /// <summary> /// 游戏面板 /// </summary> public Transform gameCanvas; /// <summary> /// 暂停面板 /// </summary> public Transform pauseCanvas; /// <summary> /// 游戏结束面板 /// </summary> public Transform gameOverCanvas; /// <summary> /// 游戏是否结束 /// </summary> internal bool isGameOver = false; /// <summary> /// 主目录场景 /// </summary> public string mainMenuLevelName = "MainMenu"; /// <summary> /// 升级声音 /// </summary> public AudioClip soundLevelUp; /// <summary> /// 游戏结束声音 /// </summary> public AudioClip soundGameOver; /// <summary> /// 使用AudioSource的物体的标签 /// </summary> public string soundSourceTag = "GameController"; /// <summary> /// 确认按钮 /// </summary> public string confirmButton = "Submit"; //暂停按钮 public string pauseButton = "Cancel"; /// <summary> /// 游戏是否暂停 /// </summary> internal bool isPaused = false; /// <summary> /// /// </summary> ; void Start() { ChangeScore(); //隐藏游戏结束面板 if( gameOverCanvas ) gameOverCanvas.gameObject.SetActive(false); //获取存档中的最高分数 highScore = PlayerPrefs.GetInt(Application.loadedLevelName + ); ; ; ; index < lanes.Length; index++) { totalLanes += lanes[index].laneChance; } lanesList = new Lane[totalLanes]; ; index < lanes.Length; index++) { ; while( laneChanceCount < lanes[index].laneChance ) { lanesList[totalLanesIndex] = lanes[index]; laneChanceCount++; totalLanesIndex++; } } ; ; ; index < objectDrops.Length; index++) { totalDrops += objectDrops[index].dropChance; } objectDropList = new Transform[totalDrops]; ; index < objectDrops.Length; index++) { ; while( dropChanceCount < objectDrops[index].dropChance ) { objectDropList[totalDropsIndex] = objectDrops[index].droppedObject; dropChanceCount++; totalDropsIndex++; } } //从存档中获取当前玩家 currentPlayer = PlayerPrefs.GetInt("CurrentPlayer", currentPlayer); SetPlayer(currentPlayer); if( cameraObject == null ) cameraObject = GameObject.FindGameObjectWithTag("MainCamera").transform; CreateLane(precreateLanes); Pause(); } void Update() { if( isGameOver == true ) { if( Input.GetButtonDown(confirmButton) ) { Restart(); } if( Input.GetButtonDown(pauseButton) ) { MainMenu(); } } else { if( Input.GetButtonDown(pauseButton) ) { if( isPaused == true ) Unpause(); else Pause(); } if ( swipeControls == true ) { ) swipeTimeoutCount -= Time.deltaTime; foreach ( Touch touch in Input.touches ) { if ( touch.phase == TouchPhase.Began ) { swipeStart = touch.position; swipeEnd = touch.position; swipeTimeoutCount = swipeTimeout; } if ( touch.phase == TouchPhase.Moved ) { swipeEnd = touch.position; } ) { if( (swipeStart.x - swipeEnd.x) > swipeDistance && (swipeStart.y - swipeEnd.y) < -swipeDistance ) { MovePlayer("left"); } else if((swipeStart.x - swipeEnd.x) < -swipeDistance && (swipeStart.y - swipeEnd.y) > swipeDistance ) { MovePlayer("right"); } else if((swipeStart.y - swipeEnd.y) < -swipeDistance && (swipeStart.x - swipeEnd.x) < -swipeDistance ) { MovePlayer("forward"); } else if((swipeStart.y - swipeEnd.y) > swipeDistance && (swipeStart.x - swipeEnd.x) > swipeDistance ) { MovePlayer("backward"); } } } } } if( nextLanePosition - cameraObject.position.x < precreateLanes ) CreateLane(); if( cameraObject ) { if( playerObjects[currentPlayer] ) cameraObject.position = ), , Mathf.Lerp(cameraObject.position.z, playerObjects[currentPlayer].position.z, Time.deltaTime * )); if( deathLineObject ) { Vector3 newVector3 = deathLineObject.position; if( cameraObject.position.x > deathLineObject.position.x ) newVector3.x = cameraObject.position.x; if( isGameOver == false ) newVector3.x += deathLineSpeed * Time.deltaTime; deathLineObject.position = newVector3; } } } /// <summary> /// 创建小路 /// </summary> /// <param name="laneCount"小路数量></param> void CreateLane(int laneCount) { ) { laneCount--; , lanesList.Length)); Transform newLane = Instantiate(lanesList[randomLane].laneObject, , ), Quaternion.identity) as Transform; if( Random.value < lanesList[randomLane].itemChance ) { Transform newObject = Instantiate(objectDropList[Mathf.FloorToInt(Random.Range(, objectDropList.Length))]) as Transform; Vector3 newVector = new Vector3(); newVector = newLane.position; newVector.z += Mathf.Round(Random.Range(-objectDropOffset, objectDropOffset)); newObject.position = newVector; } nextLanePosition += lanesList[randomLane].laneWidth; } } /// <summary> /// 改变分数 /// </summary> /// <param name="changeValue">改变的分数</param> void ChangeScore(int changeValue) { score += changeValue; //更新文本的分数显示 if( scoreText ) scoreText.GetComponent<Text>().text = score.ToString(); increaseCount += changeValue; //达到升级的条件,升级 if( increaseCount >= levelUpEveryCoins ) { increaseCount -= levelUpEveryCoins; LevelUp(); } } /// <summary> /// 升级,并增加游戏难度 /// </summary> void LevelUp() { //如果追杀物没有到达最大速度,增加它的速度 if( deathLineSpeed + deathLineSpeedIncrease < deathLineSpeedMax ) deathLineSpeed += deathLineSpeedIncrease; //播放升级声音 if( soundSourceTag != string.Empty && soundLevelUp ) GameObject.FindGameObjectWithTag(soundSourceTag).GetComponent<AudioSource>().PlayOneShot(soundLevelUp); } /// <summary> /// 暂停游戏 /// </summary> void Pause() { isPaused = true; Time.timeScale = ; //显示暂停Canvas if( pauseCanvas ) pauseCanvas.gameObject.SetActive(true); //隐藏游戏Canvas if( gameCanvas ) gameCanvas.gameObject.SetActive(false); } /// <summary> /// 取消暂停 /// </summary> void Unpause() { isPaused = false; Time.timeScale = gameSpeed; //隐藏暂停Canvas if( pauseCanvas ) pauseCanvas.gameObject.SetActive(false); //显示游戏Canvas if( gameCanvas ) gameCanvas.gameObject.SetActive(true); } /// <summary> /// 游戏结束协程 /// </summary> /// <param name="delay">等待时间</param> IEnumerator GameOver(float delay) { yield return new WaitForSeconds(delay); isGameOver = true; //删除暂停面板 if( pauseCanvas ) Destroy(pauseCanvas.gameObject); //删除游戏面板 if( gameCanvas ) Destroy(gameCanvas.gameObject); //从存档中获取所有金币数量 ); //添加本局游戏获得的得分 totalCoins += score; //将新的总得分写入存档中 PlayerPrefs.SetInt( coinsPlayerPrefs, totalCoins); if( gameOverCanvas ) { //激活游戏结束面板 gameOverCanvas.gameObject.SetActive(true); //显示本次游戏得分 gameOverCanvas.Find("TextScore").GetComponent<Text>().text = "SCORE " + score.ToString(); //设置最高得分 if( score > highScore ) { highScore = score; PlayerPrefs.SetInt(Application.loadedLevelName + "_HighScore", score); } //将最高得分显示在文本上 gameOverCanvas.Find("TextHighScore").GetComponent<Text>().text = "HIGH SCORE " + highScore.ToString(); } } /// <summary> /// 重新开始 /// </summary> void Restart() { Application.LoadLevel(Application.loadedLevelName); } /// <summary> /// 回到主目录 /// </summary> void MainMenu() { Application.LoadLevel(mainMenuLevelName); } /// <summary> /// 根据玩家编号,激活选择的玩家 /// </summary> /// <param name="playerNumber"></param> void SetPlayer( int playerNumber ) { ; index < playerObjects.Length; index++) { if ( index != playerNumber ) playerObjects[index].gameObject.SetActive(false); else playerObjects[index].gameObject.SetActive(true); } } /// <summary> /// 移动玩家 /// </summary> /// <param name="moveDirection">移动方向</param> void MovePlayer( string moveDirection ) { if ( playerObjects[currentPlayer] ) playerObjects[currentPlayer].SendMessage("Move", moveDirection); } } }
RCGGameController
using UnityEngine; namespace RoadCrossing { /// <summary> /// 小路 /// </summary> public class RCGLane : MonoBehaviour { /// <summary> /// transform缓存 /// </summary> internal Transform thisTransform; /// <summary> /// 起始位置 /// </summary> , , -); /// <summary> /// 结束位置 /// </summary> , , ); /// <summary> /// 小路上候选的移动物体数组 /// </summary> public Transform[] movingObjects; /// <summary> /// 小路上的移动物体数组 /// </summary> internal Transform[] movingObjectsList; /// <summary> /// 小路上允许存在的移动物体的数量范围 /// </summary> , ); /// <summary> /// 移动物体之间的间隔 /// </summary> ; /// <summary> /// 所有物体的移动速度范围 /// </summary> ); /// <summary> /// 物体的移动方向 /// </summary> ; /// <summary> /// 是否随机方向 /// </summary> public bool randomDirection = true; void Start() { thisTransform = transform; //满足条件改变移动方向 if( randomDirection == true && Random.value > 0.5f ) moveDirection = -; //随机选择移动速度 moveSpeed.x = Random.Range(moveSpeed.x, moveSpeed.y); //计算路的长度 float laneLength = Vector3.Distance(laneStart, laneEnd); //设置这条路上移动物体的数量 int currentMovingObjectsNumber = Mathf.FloorToInt(Random.Range(movingObjectsNumber.x, movingObjectsNumber.y)); //创建移动物体列表 movingObjectsList = new Transform[currentMovingObjectsNumber]; ; index < currentMovingObjectsNumber; index++) { //创建一个随机的移动物体 Transform newMovingObject = Instantiate(movingObjects[Mathf.FloorToInt(Random.Range(, movingObjects.Length))]) as Transform; //在小路起点放置这个物体 newMovingObject.position = thisTransform.position + laneStart; //让这个物体朝向路的终点 newMovingObject.LookAt(thisTransform.position + laneEnd); newMovingObject.Translate(Vector3.forward * index * laneLength / currentMovingObjectsNumber, Space.Self); newMovingObject.Translate(Vector3.forward * Random.Range(minimumObjectGap, laneLength / movingObjectsNumber.x - minimumObjectGap), Space.Self); //将这个物体添加到移动物体列表 movingObjectsList[index] = newMovingObject; } foreach( Transform movingObject in movingObjectsList ) { //根据方向设置移动物体的朝向,起点或终点 ) movingObject.LookAt(thisTransform.position + laneEnd); else movingObject.LookAt(thisTransform.position + laneStart); //如果又动画组件,播放动画 if( movingObject.GetComponent<Animation>() ) { //根据物体的移动速度设置动画的播放速度 movingObject.GetComponent<Animation>()[movingObject.GetComponent<Animation>().clip.name].speed = moveSpeed.x; } } } void Update() { foreach( Transform movingObject in movingObjectsList ) { if( movingObject ) { //如果移动方向等于1 ) { //从起点向小路终点移动 movingObject.position = Vector3.MoveTowards(movingObject.position, thisTransform.position + laneEnd, moveSpeed.x * Time.deltaTime); //如果到达终点,将游戏物体放到起点 if( movingObject.position == thisTransform.position + laneEnd ) { movingObject.position = thisTransform.position + laneStart; movingObject.LookAt(thisTransform.position + laneEnd); } } //如果移动方向不等于1 else { //从终点向小路起点移动 movingObject.position = Vector3.MoveTowards(movingObject.position, thisTransform.position + laneStart, moveSpeed.x * Time.deltaTime); //如果到达起点,将游戏物体放到终点 if( movingObject.position == thisTransform.position + laneStart ) { movingObject.position = thisTransform.position + laneEnd; movingObject.LookAt(thisTransform.position + laneStart); } } } } } /// <summary> /// Gizmos下画起始点和结束点 /// </summary> void OnDrawGizmos() { Gizmos.color = Color.green; Gizmos.DrawSphere(transform.position + laneStart, 0.2f); Gizmos.color = Color.red; Gizmos.DrawSphere(transform.position + laneEnd, 0.2f); } } }
RCGLane
using UnityEngine; namespace RoadCrossing { /// <summary> /// 加载场景和URL /// </summary> public class RCGLoadLevel : MonoBehaviour { /// <summary> /// 加载URL /// </summary> /// <param name="urlName"></param> public void LoadURL(string urlName) { Application.OpenURL(urlName); } /// <summary> /// 加载指定场景 /// </summary> /// <param name="levelName"></param> public void LoadLevel(string levelName) { Application.LoadLevel(levelName); } /// <summary> /// 重新加载当前场景 /// </summary> public void RestartLevel() { Application.LoadLevel(Application.loadedLevelName); } } }
RCGLoadLevel
using UnityEngine; using RoadCrossing.Types; namespace RoadCrossing { /// <summary> /// 玩家 /// </summary> public class RCGPlayer : MonoBehaviour { /// <summary> /// 缓存transform /// </summary> internal Transform thisTransform; /// <summary> /// 游戏控制器 /// </summary> internal GameObject gameController; /// <summary> /// 移动速度 /// </summary> public float speed = 0.1f; /// <summary> /// 是否正在移动 /// </summary> internal bool isMoving = false; /// <summary> /// 上一个位置 /// </summary> internal Vector3 previousPosition; /// <summary> /// 目标位置 /// </summary> internal Vector3 targetPosition; /// <summary> /// 限制玩家移动的物体 /// </summary> public Transform moveLimits; /// <summary> /// 移动动画 /// </summary> public AnimationClip animationMove; /// <summary> /// 获得金币的动画 /// </summary> public AnimationClip animationCoin; /// <summary> /// 死亡效果的动画列表 /// </summary> public Transform[] deathEffect; /// <summary> /// 从不能移动到能移动的持续时间 /// </summary> ; /// <summary> /// 移动声音 /// </summary> public AudioClip[] soundMove; /// <summary> /// 获得金币的声音 /// </summary> public AudioClip[] soundCoin; /// <summary> /// AudioSource所属的游戏物体标签 /// </summary> public string soundSourceTag = "GameController"; void Start() { thisTransform = transform; targetPosition = thisTransform.position; gameController = GameObject.FindGameObjectWithTag("GameController"); } void Update() { //让限制玩家移动的物体 跟随玩家移动 if( moveLimits ) { Vector3 newPosition = new Vector3(); newPosition.x = thisTransform.position.x; moveLimits.position = newPosition; } //计算移动延迟 ) moveDelay -= Time.deltaTime; //不处于移动状态 移动延迟<=0 时间缩放>0 && Time.timeScale > ) { //垂直抽没有输入值时,才可以左右移动 ) { //向右移动 ) { Move("right"); } //向左移动 ) { // Move one step to the left Move("left"); } } //水平轴没有输入值,才可以前后移动 ) { //向前移动 ) { Move("forward"); } //向后移动 ) { Move("backward"); } } } //其余的情况 移动玩家到目标位置 else { //保持向前移动直到 到达目标位置 if( thisTransform.position != targetPosition ) { //将玩家移动到目标位置 thisTransform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * speed); } else { //表示玩家不在移动状态中 isMoving = false; } } } /// <summary> /// 移动 /// </summary> /// <param name="moveDirection">移动方向</param> void Move(string moveDirection) { ) { isMoving = true; switch( moveDirection.ToLower() ) { //向前移动 case "forward": //让玩家朝前 Vector3 newEulerAngle = new Vector3(); newEulerAngle.y = ; thisTransform.eulerAngles = newEulerAngle; //计算目标位置 targetPosition = thisTransform.position + , , ); //让玩家在固定的网格里移动 targetPosition.x = Mathf.Round(targetPosition.x); targetPosition.z = Mathf.Round(targetPosition.z); //记录上一个位置,用来在遇到障碍物的时候,让玩家回到上一个位置 previousPosition = thisTransform.position; break; case "backward": //让玩家朝后 newEulerAngle = new Vector3(); newEulerAngle.y = ; thisTransform.eulerAngles = newEulerAngle; //记录上一个位置,用来在遇到障碍物的时候,让玩家回到上一个位置 previousPosition = thisTransform.position; //让玩家在固定的网格里移动 targetPosition.x = Mathf.Round(targetPosition.x); targetPosition.z = Mathf.Round(targetPosition.z); //计算目标位置 targetPosition = thisTransform.position + , , ); break; case "right": //让玩家朝向右 newEulerAngle = new Vector3(); newEulerAngle.y = ; thisTransform.eulerAngles = newEulerAngle; //记录上一个位置,用来在遇到障碍物的时候,让玩家回到上一个位置 previousPosition = thisTransform.position; //让玩家在固定的网格里移动 targetPosition.x = Mathf.Round(targetPosition.x); targetPosition.z = Mathf.Round(targetPosition.z); //计算目标位置 targetPosition = thisTransform.position + , , -); break; case "left": //让玩家朝向左 newEulerAngle = new Vector3(); newEulerAngle.y = -; thisTransform.eulerAngles = newEulerAngle; //记录上一个位置,用来在遇到障碍物的时候,让玩家回到上一个位置 previousPosition = thisTransform.position; //让玩家在固定的网格里移动 targetPosition.x = Mathf.Round(targetPosition.x); targetPosition.z = Mathf.Round(targetPosition.z); //计算目标位置 targetPosition = thisTransform.position + , , ); break; default: //让玩家朝前 newEulerAngle = new Vector3(); newEulerAngle.y = ; thisTransform.eulerAngles = newEulerAngle; //计算目标位置 targetPosition = thisTransform.position + , , ); //归一化目标位置 targetPosition.Normalize(); //记录上一个位置,用来在遇到障碍物的时候,让玩家回到上一个位置 previousPosition = thisTransform.position; break; } //满足条件 播放移动动画 if( GetComponent<Animation>() && animationMove ) { GetComponent<Animation>().Stop(); GetComponent<Animation>().Play(animationMove.name); //基于移动速度设置动画速度 GetComponent<Animation>()[animationMove.name].speed = speed; //满足条件播放移动声音 ) GameObject.FindGameObjectWithTag(soundSourceTag).GetComponent<AudioSource>().PlayOneShot(soundMove[Mathf.FloorToInt(Random.value * soundMove.Length)]); } } } /// <summary> /// 取消玩家的移动,将玩家弹回到前一个位置 /// </summary> void CancelMove(float moveDelayTime) { //满足条件播放动画 if( GetComponent<Animation>() && animationMove ) { //基于移动速度,倒放动画 GetComponent<Animation>()[animationMove.name].speed = -speed; } //将目标位置设置为前一个位置 targetPosition = previousPosition; //设置移动延迟 moveDelay = moveDelayTime; } /// <summary> /// 获得金币 /// </summary> void AddCoin(int addValue) { //调用游戏控制里的改变分数方法 gameController.SendMessage("ChangeScore", addValue); //播放获得金币动画 if( GetComponent<Animation>() && animationCoin && animationMove ) { GetComponent<Animation>()[animationCoin.name].layer = ; GetComponent<Animation>().Play(animationCoin.name); GetComponent<Animation>()[animationCoin.name].weight = 0.5f; } //播放获得金币声音 ) GameObject.FindGameObjectWithTag(soundSourceTag).GetComponent<AudioSource>().PlayOneShot(soundCoin[Mathf.FloorToInt(Random.value * soundCoin.Length)]); } /// <summary> /// 死亡 /// </summary> /// <param name="deathType">死亡效果类型</param> void Die(int deathType) { //调用游戏控制器的游戏结束方法 gameController.SendMessage("GameOver", 0.5f); //创建死亡特效 ) { Instantiate(deathEffect[deathType], thisTransform.position, thisTransform.rotation); } //销毁游戏物体 Destroy(gameObject); } } }
RCGPlayer
using UnityEngine; namespace RoadCrossing { /// <summary> /// 播放声音 /// </summary> public class RCGPlaySound : MonoBehaviour { /// <summary> /// 声音数组 /// </summary> public AudioClip[] audioList; /// <summary> /// AudioSource所在物体的标签 /// </summary> public string audioSourceTag = "GameController"; /// <summary> /// 游戏开始时是否播放 /// </summary> public bool playOnStart = true; void Start() { if( playOnStart == true ) PlaySound(); } /// <summary> /// 播放声音 /// </summary> void PlaySound() { ) GameObject.FindGameObjectWithTag(audioSourceTag).GetComponent<AudioSource>().PlayOneShot(audioList[Mathf.FloorToInt(Random.value * audioList.Length)]); } /// <summary> /// 根据索引播放声音 /// </summary> void PlaySound(int soundIndex) { ) GameObject.FindGameObjectWithTag(audioSourceTag).GetComponent<AudioSource>().PlayOneShot(audioList[soundIndex]); } } }
RCGPlaySound
using UnityEngine; namespace RoadCrossing { /// <summary> /// 随机化物体的颜色 /// </summary> public class RCGRandomizeColor : MonoBehaviour { /// <summary> /// 颜色数组 /// </summary> public Color[] colorList; void Start() { //随机选择一个颜色 , colorList.Length)); //将颜色应用到物体和子物体上 Component[] comps = GetComponentsInChildren<Renderer>(); foreach( Renderer part in comps ) part.GetComponent<Renderer>().material.color = colorList[randomColor]; } } }
RCGRandomizeColor
using UnityEngine; namespace RoadCrossing { /// <summary> /// 随机化物体的旋转,缩放和颜色 /// </summary> public class RCGRandomizeTransform : MonoBehaviour { /// <summary> /// x轴的旋转范围 /// </summary> , ); /// <summary> /// y轴的旋转范围 /// </summary> , ); /// <summary> /// z轴的旋转范围 /// </summary> , ); /// <summary> /// x轴缩放范围 /// </summary> , 1.3f); /// <summary> /// y轴缩放范围 /// </summary> , 1.3f); /// <summary> /// z轴缩放范围 /// </summary> , 1.3f); /// <summary> /// 是否统一比例缩放 /// </summary> public bool uniformScale = true; /// <summary> /// 颜色列表 /// </summary> public Color[] colorList; void Start() { //随机旋转 transform.localEulerAngles = new Vector3(Random.Range(rotationRangeX.x, rotationRangeX.y), Random.Range(rotationRangeY.x, rotationRangeY.y), Random.Range(rotationRangeZ.x, rotationRangeZ.y)); //如果是统一缩放,让y,z轴基于x轴的比例缩放 if( uniformScale == true ) scaleRangeY = scaleRangeZ = scaleRangeX; //随机缩放 transform.localScale = new Vector3(Random.Range(scaleRangeX.x, scaleRangeX.y), Random.Range(scaleRangeY.x, scaleRangeY.y), Random.Range(scaleRangeZ.x, scaleRangeZ.y)); //随机颜色 , colorList.Length)); Component[] comps = GetComponentsInChildren<Renderer>(); foreach( Renderer part in comps ) part.GetComponent<Renderer>().material.color = colorList[randomColor]; } } }
RCGRandomizeTransform
using UnityEngine; namespace RoadCrossing { /// <summary> /// 经过一段时间后删除物体,用来在特效播放完成后删除特效 /// </summary> public class RCGRemoveAfter : MonoBehaviour { //删除物体的等待时间 ; void Update() { removeAfter -= Time.deltaTime; ) Destroy(gameObject); } } }
RCGRemoveAfter
using UnityEngine; using System.Collections; using UnityEngine.UI; using RoadCrossing.Types; namespace RoadCrossing { /// <summary> /// 商店 /// </summary> public class RCGShop : MonoBehaviour { /// <summary> /// 剩余的金币数量 /// </summary> ; /// <summary> /// 显示金币的文本 /// </summary> public Transform coinsText; /// <summary> /// 玩家的金币值 /// </summary> public string coinsPlayerPrefs = "Coins"; /// <summary> /// 商店道具列表 /// </summary> public ShopItem[] shopItems; /// <summary> /// 当前道具 /// </summary> ; /// <summary> /// 存档里的当前玩家键 /// </summary> public string playerPrefsName = "CurrentPlayer"; /// <summary> /// 道具的未被选择时的颜色 /// </summary> ); /// <summary> /// 道具的选中颜色 /// </summary> ,,,); /// <summary> /// 暂未使用 /// </summary> ,,,); void Start() { //获取剩余金币 coinsLeft = PlayerPrefs.GetInt(coinsPlayerPrefs, coinsLeft); //更新金币文本 coinsText.GetComponent<Text>().text = coinsLeft.ToString(); //获取当前道具 currentItem = PlayerPrefs.GetInt(playerPrefsName, currentItem); //更新所有道具 UpdateItems(); } /// <summary> /// 更新道具 /// </summary> void UpdateItems() { ; index < shopItems.Length ; index++ ) { //从存档中获取这个道具的解锁状态 shopItems[index].lockState = PlayerPrefs.GetInt(shopItems[index].playerPrefsName, shopItems[index].lockState); //设置道具的颜色为 未选择的颜色 shopItems[index].itemButton.GetComponent<Image>().color = unselectedColor; //如果这个道具已经解锁 ) { //禁用显示价格的物体 shopItems[index].itemButton.Find("TextPrice").gameObject.SetActive(false); //高亮当前选择的物体的颜色 if ( index == currentItem ) shopItems[index].itemButton.GetComponent<Image>().color = selectedColor; } //如果没有解锁 else { //更新这个道具的价格 shopItems[index].itemButton.Find("TextPrice").GetComponent<Text>().text = shopItems[index].costToUnlock.ToString(); } } } /// <summary> /// 买道具 /// </summary> /// <param name="itemNumber"></param> void BuyItem( int itemNumber ) { //如果这个道具已解锁,选择这个道具 ) { SelectItem(itemNumber); } //如果有足够的金币,消耗金币买这个道具 else if ( shopItems[itemNumber].costToUnlock <= coinsLeft ) { //解锁道具 shopItems[itemNumber].lockState = ; //在存档中更新这个道具的状态 PlayerPrefs.SetInt(shopItems[itemNumber].playerPrefsName, shopItems[itemNumber].lockState); //扣除金币 coinsLeft -= shopItems[itemNumber].costToUnlock; //更新文本 coinsText.GetComponent<Text>().text = coinsLeft.ToString(); //将剩余金币写入Prefs PlayerPrefs.SetInt(coinsPlayerPrefs, coinsLeft); //选择道具 SelectItem(itemNumber); } UpdateItems(); } /// <summary> /// 选择道具 /// </summary> /// <param name="itemNumber"></param> void SelectItem( int itemNumber ) { currentItem = itemNumber; PlayerPrefs.SetInt( playerPrefsName, itemNumber); } } }
RCGShop
using UnityEngine; using System.Collections; using UnityEngine.UI; namespace RoadCrossing { /// <summary> /// 显示文本 /// </summary> public class RCGTextByPlatform : MonoBehaviour { /// <summary> /// 显示在PC/Mac/Webplayer中的文本 /// </summary> public string computerText = "CLICK TO START"; /// <summary> /// 显示在Android/iOS/WinPhone中的文本 /// </summary> public string mobileText = "TAP TO START"; /// <summary> /// 显示在Playstation/Xbox/Wii中的文本 /// </summary> public string consoleText = "PRESS 'A' TO START"; void Start() { #if UNITY_STANDALONE || UNITY_WEBPLAYER GetComponent<Text>().text = computerText; #endif #if IPHONE || ANDROID || UNITY_BLACKBERRY || UNITY_WP8 || UNITY_METRO GetComponent<Text>().text = mobileText; #endif #if UNITY_WII || UNITY_PS3 || UNITY_XBOX360 GetComponent<Text>().text = consoleText; #endif } } }
RCGTextByPlatform
using UnityEngine; using System.Collections; using UnityEngine.UI; namespace RoadCrossing { /// <summary> /// 声音开关 /// </summary> public class RCGToggleSound:MonoBehaviour { /// <summary> /// 播放声音的物体 /// </summary> public Transform soundObject; /// <summary> /// 存档中的名称 /// </summary> public string playerPref = "SoundVolume"; /// <summary> /// 声音的当前音量 /// </summary> ; void Awake() { if( soundObject ) currentState = PlayerPrefs.GetFloat(playerPref, soundObject.GetComponent<AudioSource>().volume); else currentState = PlayerPrefs.GetFloat(playerPref, currentState); SetSound(); } /// <summary> /// 设置声音大小 /// </summary> void SetSound() { //设置声音存档 PlayerPrefs.SetFloat(playerPref, currentState); Color newColor = GetComponent<Image>().material.color; //根据声音存档值设置按钮透明度 ) newColor.a = ; else newColor.a = 0.5f; //应用透明度 GetComponent<Image>().color = newColor; //设置音量 if( soundObject ) soundObject.GetComponent<AudioSource>().volume = currentState; } /// <summary> /// 开关声音 /// </summary> void ToggleSound() { currentState = - currentState; SetSound(); } /// <summary> /// 播放声音 /// </summary> void StartSound() { if( soundObject ) soundObject.GetComponent<AudioSource>().Play(); } } }
RCGToggleSound
视频:https://pan.baidu.com/s/1qYPhpsK
项目:https://pan.baidu.com/s/1mi5C7s0
Road Crossing Game Template 学习的更多相关文章
- template学习一函数模板
要点: 1.模板参数在实体化的时候不能自动类型转换,只有非模板函数才可以 例如: int max(int,int); template <class T> T max(T,T); 在调用的 ...
- C++ template学习二 类模板定义及实例化
一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员.默写成员函数的参数.某些成员函数的返回值,能够取任意类型(包括系统预定义的和用户自定义的). 如果一个类中数据成员 ...
- C++ template学习一(函数模板和模板函数)
函数模板和模板函数(1)函数模板函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计.它的最大特点是把函数使用的数据类型作为参数.函数模板的声明形式为:templat ...
- jQuery .tmpl(), .template()学习资料小结
昨晚无意中发现一个有趣的jQuery插件.tmpl(),其文档在这里.官方解释对该插件的说明:将匹配的第一个元素作为模板,render指定的数据,签名如下: .tmpl([data,][options ...
- Elasticsearch template学习
Elasticsearch template Elasticsearch存在一个关键问题就是索引的设置及字段的属性指定,最常见的问题就是,某个字段我们并不希望ES对其进行分词,但如果使用自动模板创建索 ...
- jQuery.template.js 简单使用
之前看了一篇文章<我们为什么要尝试前后端分离>,深有同感,并有了下面的评论: 我最近也和前端同事在讨论这个问题,比如有时候前端写好页面给后端了,然后后端把这些页面拆分成很多的 views, ...
- 模板学习实践二 pointer
c++ template学习记录 使用模板将实际类型的指针进行封装 当变量退出作用域 自动delete // 1111.cpp : 定义控制台应用程序的入口点. // #include "s ...
- DCN模型
1. DCN优点 使用Cross Network,在每一层都运用了Feature Crossing,高效学习高阶特征. 网络结构简单且高效 相比DNN,DCN的Logloss值更低,而且参数的数量少了 ...
- The Road to learn React书籍学习笔记(第三章)
The Road to learn React书籍学习笔记(第三章) 代码详情 声明周期方法 通过之前的学习,可以了解到ES6 类组件中的生命周期方法 constructor() 和 render() ...
随机推荐
- 201621123001《Java程序设计》第4周学习总结
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键字:继承,多态,覆盖(Override),重载(Overload),抽象类(abstract)等. 1.2 尝试使用思维导图 ...
- shell脚本实例-mysql多机部署
今天我给大家分享shell 安装mysql 多机部署的实例,本次实验是基于各个主机的公钥已经配置好了,如果还不会推送公钥的同学,可以看看我以前写的文章,那里面有写推公钥的实例,mysql 多机部署一般 ...
- 32位linux(ubuntu) exec: arm-none-linux-gnueabi-g++未找到;The tslib functionality test failed!
请先参考:http://blog.csdn.net/ankwyq/article/details/7768809 通过上面那篇文章,我确实把问题又推进了一步,接下来就是下面这个问题: exec: ar ...
- ios遮罩层的简单使用
/** 大图 */ - (IBAction)bigImg { //1.添加按钮遮罩层 UIButton *cover=[[UIButton alloc] init]; cover.frame=self ...
- switfmailer 邮件时间错误 处理
Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use ...
- kbmMW授权管理解析(The kbmMW Authorization manager explained)
从kbmMW v.4.40开始,引入了一个新的非常灵活的授权管理器. 它的目的是为开发人员提供为用户定义资源权限的功能,这是一个可选功能,将现有的授权事件驱动方案内置到kbmMW中,使授权开发任务更容 ...
- 性能测试-11.Linux服务器使用NMON监控指标
一.NMON使用 首先下载nmon软件http://nmon.sourceforge.net/pmwiki.php?n=Site.Download,打开这个网站下载符合自己操作系统的硬件的相关nmon ...
- Vue 之 Vue.nextTick()
异步更新队列 可能你还没有注意到,Vue 异步执行 DOM 更新.只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变.如果同一个 watcher 被多次触发,只会一次 ...
- Django之路由控制配置
路由控制配置 简单的路由配置 Django即支持1.x版本的路由配置也支持2.x的路由配置 1.x版本的路由配置是使用re进行路由配置(re_path) 2.x版本的路由配置使用(path)进行路由配 ...
- 本地存储之application cache和localstorage
http://blog.csdn.net/kingliguo/article/details/52637087