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() ...
随机推荐
- java泛型讲解
原文: https://blog.csdn.net/briblue/article/details/76736356 泛型,一个孤独的守门者. 大家可能会有疑问,我为什么叫做泛型是一个守门者.这其实是 ...
- 虚拟机中扩展linux系统存储空间
reference: https://blog.csdn.net/greenapple_shan/article/details/52799631 https://blog.csdn.net/lyd1 ...
- L230 RF可靠性测试-RF指标
最近调试Zigbee 和2.4G产品时需要做一些认证,查找到常用的RF指标. ----------http://www.52rd.com/S_TXT/2016_5/TXT83303.htm------ ...
- day 关于生成器的函数
def average(): count=0 toatal=0 average=0 while True: value=yield average toatal+=value count+=1 ave ...
- 2-log4j2之使用根控制器输出日志到控制台
一.添加maven依赖 <!-- 使用aliyun镜像 --> <repositories> <repository> <id>aliyun</i ...
- 解决The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
SpringMVC中当在浏览器中输入对应的MappingUrl时,报The resource identified by this request is only capable of generat ...
- JAVA自动补全代码
打开eclipse(对myeclipse同样适用) 找到窗口(windows)菜单,打开最后一项首选项(Preferences)找到下属菜单java打开,打开里边的编辑器(Editor)菜单,点击内容 ...
- 2--Jmeter 4.0--Excel 数据驱动 接口测试
Excel 模板 通过jmeter的csv data set config 读取 Jmeter注意事项 (1)数据驱动 1..JDBC :SQL 存储在excel中,无法将where条件对应的jmet ...
- JAVA将单词首字母大写方法
public class FirstLetterUppercase { public static void main(String[] args){ System.out.println(new F ...
- poj 2175 费用流消圈
题意抽象出来就是给了一个费用流的残存网络,判断该方案是不是最优方案,如果不是,还要求给出一个更优方案. 在给定残存网络上检查是否存在负环即可判断是否最优. 沿负环增广一轮即可得到更优方案. 考虑到制作 ...