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() ...
随机推荐
- 2.Python爬虫入门二之爬虫基础了解
1.什么是爬虫 爬虫,即网络爬虫,大家可以理解为在网络上爬行的一直蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓取下来.想抓取什么?这个由你来控制它咯. ...
- python+appium+yaml安卓UI自动化测试分享
一.实现数据与代码分离,维护成本较低,先看看自动化结构,大体如下: testyaml管理用例,实现数据与代码分离,一个模块一个文件夹 public 存放公共文件,如读取配置文件.启动appium服务. ...
- mysql ON DUPLICATE KEY UPDATE ; 以及 同replace to 的区别.
需求: 1)如果admin表中没有数据, 插入一条 2)如果admin表中有数据, 不插入. 一般做法: if($result = mysql_query("select * from ad ...
- 在Linux系统下mail命令的用法
在Linux系统下mail命令的测试 1. 最简单的一个例子: mail -s test admin@aispider.com 这条命令的结果是发一封标题为test的空信给后面的邮箱,如果你有mta并 ...
- 【Python】unittest-2-断言
Unittest中的断言 1. python unintest单元测试框架提供了一整套内置的断言方法. (1)如果断言失败,则抛出一个AssertionError,并标识该测试为失败状态 (2)如果 ...
- 2.11 alert\confirm\prompt
2.11 alert\confirm\prompt 前言 不是所有的弹出框都叫alert,在使用alert方法前,先要识别出到底是不是alert.先认清楚alert长什么样子,下次碰到了,就可以用 ...
- python3.6升级
Ubuntu 14.04 and 16.04 If you are using Ubuntu 14.04 or 16.04, you can use Felix Krull's deadsnakes ...
- sizeof和strlen区别(转)
char str[20]="0123456789"; int a=strlen(str); /*a=10;strlen 计算字符串的长度,以\0'为字符串结束标记. int ...
- OpenCV 自定义任意区域形状及计算平均值 方差
opencv中有矩形的Rect函数.圆形的circl函数等,那么任意形状怎么取呢?方法1:点乘,将其形状与图像进行点乘,求其形状对应的图像形状:方法2:用findContours函数得对应的形状区域, ...
- 20155219&20155224 《信息安全系统设计基础》实验二 固件程序设计
实验二 固件程序设计-1-MDK 0. 注意不经老师允许不准烧写自己修改的代码 1. 两人(个别三人)一组 2. 参考云班课资源中"信息安全系统实验箱指导书.pdf "第一章,1. ...