2D Platformer 学习


using UnityEngine;
using System.Collections;
/// <summary>
/// 玩家控制
/// </summary>
public class PlayerControl : MonoBehaviour
{
/// <summary>
/// 是否面向右边
/// </summary>
[HideInInspector]
public bool facingRight = true;
/// <summary>
/// 是否在跳跃状态
/// </summary>
[HideInInspector]
public bool jump = false;
/// <summary>
/// 玩家左右移动的力
/// </summary>
public float moveForce = 365f;
/// <summary>
/// 玩家在x轴的最大移动速度
/// </summary>
public float maxSpeed = 5f;
/// <summary>
/// 跳跃声音
/// </summary>
public AudioClip[] jumpClips;
/// <summary>
/// 跳跃力
/// </summary>
public float jumpForce = 1000f;
/// <summary>
/// 嘲讽声音
/// </summary>
public AudioClip[] taunts;
/// <summary>
/// 嘲讽阈值
/// </summary>
public float tauntProbability = 50f;
/// <summary>
/// 嘲讽延迟
/// </summary>
public float tauntDelay = 1f;
/// <summary>
/// 上一次的嘲讽索引
/// </summary>
private int tauntIndex;
/// <summary>
/// 检查玩家是否在地上的go
/// </summary>
private Transform groundCheck;
/// <summary>
/// 玩家是否在地上
/// </summary>
private bool grounded = false;
/// <summary>
/// Animator
/// </summary>
private Animator anim;
void Awake()
{
groundCheck = transform.Find("groundCheck");
anim = GetComponent<Animator>();
}
void Update()
{
//发射射线检测玩家是否在地面
grounded = Physics2D.Linecast(transform.position, groundCheck.position, << LayerMask.NameToLayer("Ground"));
//如果按下跳跃键且玩家在地上,玩家跳
if(Input.GetButtonDown("Jump") && grounded)
jump = true;
}
void FixedUpdate ()
{
//获取水平的输入
float h = Input.GetAxis("Horizontal");
//设置水平方向的移动速度
anim.SetFloat("Speed", Mathf.Abs(h));
//如果玩家速度没有到达最大速度,让玩家到达最大速度
if(h * GetComponent<Rigidbody2D>().velocity.x < maxSpeed)
GetComponent<Rigidbody2D>().AddForce(Vector2.right * h * moveForce);
//如果x轴的速度大于最大速度,限制玩家速度为最大速度
if(Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x) > maxSpeed)
GetComponent<Rigidbody2D>().velocity = new Vector2(Mathf.Sign(GetComponent<Rigidbody2D>().velocity.x) * maxSpeed, GetComponent<Rigidbody2D>().velocity.y);
//设置玩家的朝向
&& !facingRight)
Flip();
&& facingRight)
Flip();
//如果玩家跳
if(jump)
{
//播放跳动画
anim.SetTrigger("Jump");
//随机播放跳跃声音
, jumpClips.Length);
AudioSource.PlayClipAtPoint(jumpClips[i], transform.position);
//添加跳跃力
GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce));
//设置跳跃标志位为false
jump = false;
}
}
/// <summary>
/// 转向
/// </summary>
void Flip ()
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -;
transform.localScale = theScale;
}
/// <summary>
/// 嘲讽协程
/// </summary>
/// <returns></returns>
public IEnumerator Taunt()
{
//计算嘲讽几率
float tauntChance = Random.Range(0f, 100f);
//如果嘲讽几率大于阈值
if(tauntChance > tauntProbability)
{
yield return new WaitForSeconds(tauntDelay);
if(!GetComponent<AudioSource>().isPlaying)
{
tauntIndex = TauntRandom();
GetComponent<AudioSource>().clip = taunts[tauntIndex];
GetComponent<AudioSource>().Play();
}
}
}
/// <summary>
/// 随机播放嘲讽
/// </summary>
/// <returns></returns>
int TauntRandom()
{
, taunts.Length);
//如果和上次的嘲讽索引一样,再随机一次
if(i == tauntIndex)
return TauntRandom();
else
return i;
}
}
PlayerControl
using UnityEngine;
using System.Collections;
/// <summary>
/// 玩家生命
/// </summary>
public class PlayerHealth : MonoBehaviour
{
/// <summary>
/// 玩家生命
/// </summary>
public float health = 100f;
/// <summary>
/// 玩家能被伤害的时间间隔
/// </summary>
public float repeatDamagePeriod = 2f;
/// <summary>
/// 玩家受到伤害的声音数组
/// </summary>
public AudioClip[] ouchClips;
/// <summary>
/// 玩家受到伤害时受到的力
/// </summary>
public float hurtForce = 10f;
/// <summary>
/// 敌人碰到玩家后,玩家受到的伤害
/// </summary>
public float damageAmount = 10f;
/// <summary>
/// 玩家血条
/// </summary>
private SpriteRenderer healthBar;
/// <summary>
/// 上一次受到的伤害
/// </summary>
private float lastHitTime;
/// <summary>
/// 血条缩放
/// </summary>
private Vector3 healthScale;
/// <summary>
/// 玩家控制
/// </summary>
private PlayerControl playerControl;
/// <summary>
/// Animator
/// </summary>
private Animator anim;
void Awake ()
{
playerControl = GetComponent<PlayerControl>();
healthBar = GameObject.Find("HealthBar").GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
healthScale = healthBar.transform.localScale;
}
void OnCollisionEnter2D (Collision2D col)
{
//如果碰到敌人
if(col.gameObject.tag == "Enemy")
{
//如果时间大于 上次受到伤害的时间 + 玩家能被伤害的时间间隔
if (Time.time > lastHitTime + repeatDamagePeriod)
{
//如果玩家生命>0
if(health > 0f)
{
TakeDamage(col.transform);
//设置上次受到伤害的时间
lastHitTime = Time.time;
}
//如果玩家生命<=,让玩家掉下河
else
{
//将玩家的碰撞器修改为触发器
Collider2D[] cols = GetComponents<Collider2D>();
foreach(Collider2D c in cols)
{
c.isTrigger = true;
}
//修改玩家及其子物体的 SorintLayer
SpriteRenderer[] spr = GetComponentsInChildren<SpriteRenderer>();
foreach(SpriteRenderer s in spr)
{
s.sortingLayerName = "UI";
}
//关闭玩家控制脚本
GetComponent<PlayerControl>().enabled = false;
//关闭 gun脚本
GetComponentInChildren<Gun>().enabled = false;
//播放死亡动画
anim.SetTrigger("Die");
}
}
}
}
/// <summary>
/// 受到伤害
/// </summary>
/// <param name="enemy"></param>
void TakeDamage (Transform enemy)
{
//让玩家不能跳
playerControl.jump = false;
//设置受伤的方向
Vector3 hurtVector = transform.position - enemy.position + Vector3.up * 5f;
//给刚体施加力
GetComponent<Rigidbody2D>().AddForce(hurtVector * hurtForce);
//减血
health -= damageAmount;
//更新血条
UpdateHealthBar();
//随机播放受到伤害的声音
, ouchClips.Length);
AudioSource.PlayClipAtPoint(ouchClips[i], transform.position);
}
/// <summary>
/// 更新血条
/// </summary>
public void UpdateHealthBar ()
{
//设置血条颜色
healthBar.material.color = Color.Lerp(Color.green, Color.red, - health * 0.01f);
//设置血条缩放
healthBar.transform.localScale = , );
}
}
PlayerHealth
using UnityEngine;
using System.Collections;
/// <summary>
/// 玩家放置炸弹
/// </summary>
public class LayBombs : MonoBehaviour
{
/// <summary>
/// 炸弹是否已放置
/// </summary>
[HideInInspector]
public bool bombLaid = false;
/// <summary>
/// 玩家拥有的炸弹数量
/// </summary>
;
/// <summary>
/// 放置炸弹的声音
/// </summary>
public AudioClip bombsAway;
/// <summary>
/// 炸弹预设
/// </summary>
public GameObject bomb;
/// <summary>
/// 炸弹HUD
/// </summary>
private GUITexture bombHUD;
void Awake ()
{
bombHUD = GameObject.Find("ui_bombHUD").GetComponent<GUITexture>();
}
void Update ()
{
//放置炸弹
)
{
bombCount--;
bombLaid = true;
AudioSource.PlayClipAtPoint(bombsAway,transform.position);
Instantiate(bomb, transform.position, transform.rotation);
}
bombHUD.enabled = bombCount > ;
}
}
LayBombs
using UnityEngine;
using System.Collections;
/// <summary>
/// 玩家的枪
/// </summary>
public class Gun : MonoBehaviour
{
/// <summary>
/// 火箭预设
/// </summary>
public Rigidbody2D rocket;
/// <summary>
/// 火箭速度
/// </summary>
public float speed = 20f;
/// <summary>
/// 玩家控制
/// </summary>
private PlayerControl playerCtrl;
/// <summary>
/// Animator
/// </summary>
private Animator anim;
void Awake()
{
anim = transform.root.gameObject.GetComponent<Animator>();
playerCtrl = transform.root.GetComponent<PlayerControl>();
}
void Update ()
{
//按下发射键
if(Input.GetButtonDown("Fire1"))
{
//播放动画
anim.SetTrigger("Shoot");
//播放声音
GetComponent<AudioSource>().Play();
//玩家朝右
if(playerCtrl.facingRight)
{
//实例化向右的子弹
Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(,,))) as Rigidbody2D;
bulletInstance.velocity = );
}
//玩家朝左
else
{
//实例化向左的子弹
Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(,,180f))) as Rigidbody2D;
bulletInstance.velocity = );
}
}
}
}
Gun
using UnityEngine;
using System.Collections;
/// <summary>
/// 火箭
/// </summary>
public class Rocket : MonoBehaviour
{
/// <summary>
/// 爆炸预设
/// </summary>
public GameObject explosion;
void Start ()
{
//炸弹没有碰到任何东西,默认2秒内销毁
Destroy(gameObject, );
}
/// <summary>
/// 爆炸
/// </summary>
void OnExplode()
{
//实例化爆炸效果,让爆炸效果在z轴随机旋转
Quaternion randomRotation = Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
Instantiate(explosion, transform.position, randomRotation);
}
void OnTriggerEnter2D (Collider2D col)
{
//撞到敌人
if(col.tag == "Enemy")
{
//敌人受伤
col.gameObject.GetComponent<Enemy>().Hurt();
OnExplode();
Destroy (gameObject);
}
//撞到炸弹收集物
else if(col.tag == "BombPickup")
{
//炸弹爆炸
col.gameObject.GetComponent<Bomb>().Explode();
Destroy (col.transform.root.gameObject);
Destroy (gameObject);
}
//其余情况
else if(col.gameObject.tag != "Player")
{
OnExplode();
Destroy (gameObject);
}
}
}
Rocket
using UnityEngine;
using System.Collections;
/// <summary>
/// 自动销毁
/// </summary>
public class Destroyer : MonoBehaviour
{
/// <summary>
/// 是否在开始时间就进入自动销毁
/// </summary>
public bool destroyOnAwake;
/// <summary>
/// 自动销毁的延迟
/// </summary>
public float awakeDestroyDelay;
/// <summary>
/// 是否查找子物体
/// </summary>
public bool findChild = false;
/// <summary>
/// 子物体的名称
/// </summary>
public string namedChild;
void Awake ()
{
if(destroyOnAwake)
{
if(findChild)
{
Destroy (transform.Find(namedChild).gameObject);
}
else
{
Destroy(gameObject, awakeDestroyDelay);
}
}
}
/// <summary>
/// 销毁子物体
/// </summary>
void DestroyChildGameObject ()
{
if(transform.Find(namedChild).gameObject != null)
Destroy (transform.Find(namedChild).gameObject);
}
/// <summary>
/// 禁用子物体
/// </summary>
void DisableChildGameObject ()
{
if(transform.Find(namedChild).gameObject.activeSelf == true)
transform.Find(namedChild).gameObject.SetActive(false);
}
/// <summary>
/// 销毁物体
/// </summary>
void DestroyGameObject ()
{
Destroy (gameObject);
}
}
Destroyer
using UnityEngine;
using System.Collections;
/// <summary>
/// 血条跟随玩家
/// </summary>
public class FollowPlayer : MonoBehaviour
{
/// <summary>
/// 相对于玩家的偏移
/// </summary>
public Vector3 offset;
/// <summary>
/// 玩家
/// </summary>
private Transform player;
void Awake ()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update ()
{
transform.position = player.position + offset;
}
}
FollowPlayer
using UnityEngine;
using System.Collections;
/// <summary>
/// 收集物的孵化器
/// </summary>
public class PickupSpawner : MonoBehaviour
{
/// <summary>
/// 收集物预设
/// </summary>
public GameObject[] pickups;
/// <summary>
/// 收集物在空中的时间
/// </summary>
public float pickupDeliveryTime = 5f;
/// <summary>
/// 掉落范围左
/// </summary>
public float dropRangeLeft;
/// <summary>
/// 掉落范围右
/// </summary>
public float dropRangeRight;
/// <summary>
/// 高于这个阈值,投递炸弹
/// </summary>
public float highHealthThreshold = 75f;
/// <summary>
/// 低于这个阈值,投递血药
/// </summary>
public float lowHealthThreshold = 25f;
/// <summary>
/// 玩家血量
/// </summary>
private PlayerHealth playerHealth;
void Awake ()
{
playerHealth = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerHealth>();
}
void Start ()
{
StartCoroutine(DeliverPickup());
}
/// <summary>
/// 派送收集物协程
/// </summary>
/// <returns></returns>
public IEnumerator DeliverPickup()
{
yield return new WaitForSeconds(pickupDeliveryTime);
//随机获得掉落在x轴的位置
float dropPosX = Random.Range(dropRangeLeft, dropRangeRight);
//计算掉落位置
Vector3 dropPos = new Vector3(dropPosX, 15f, 1f);
//高于阈值,实例化炸弹
if(playerHealth.health >= highHealthThreshold)
Instantiate(pickups[], dropPos, Quaternion.identity);
//低于阈值,实例化药
else if(playerHealth.health <= lowHealthThreshold)
Instantiate(pickups[], dropPos, Quaternion.identity);
//随机实例化
else
{
, pickups.Length);
Instantiate(pickups[pickupIndex], dropPos, Quaternion.identity);
}
}
}
PickupSpawner
using UnityEngine;
using System.Collections;
/// <summary>
/// 炸弹收集物
/// </summary>
public class BombPickup : MonoBehaviour
{
/// <summary>
/// 收集声音
/// </summary>
public AudioClip pickupClip;
/// <summary>
/// Animator
/// </summary>
private Animator anim;
/// <summary>
/// 是否着陆
/// </summary>
private bool landed = false;
void Awake()
{
anim = transform.root.GetComponent<Animator>();
}
void OnTriggerEnter2D (Collider2D other)
{
//碰到玩家
if(other.tag == "Player")
{
AudioSource.PlayClipAtPoint(pickupClip, transform.position);
other.GetComponent<LayBombs>().bombCount++;
Destroy(transform.root.gameObject);
}
//碰到地面
else if(other.tag == "ground" && !landed)
{
anim.SetTrigger("Land");
transform.parent = null;
gameObject.AddComponent<Rigidbody2D>();
landed = true;
}
}
}
BombPickup
using UnityEngine;
using System.Collections;
/// <summary>
/// 生命收集物
/// </summary>
public class HealthPickup : MonoBehaviour
{
/// <summary>
/// 提供的生命值
/// </summary>
public float healthBonus;
/// <summary>
/// 被收集后的声音
/// </summary>
public AudioClip collect;
/// <summary>
/// 收集物孵化器
/// </summary>
private PickupSpawner pickupSpawner;
/// <summary>
/// Animator
/// </summary>
private Animator anim;
/// <summary>
/// 是否着陆
/// </summary>
private bool landed;
void Awake ()
{
pickupSpawner = GameObject.Find("pickupManager").GetComponent<PickupSpawner>();
anim = transform.root.GetComponent<Animator>();
}
void OnTriggerEnter2D (Collider2D other)
{
//如果碰到玩家
if(other.tag == "Player")
{
PlayerHealth playerHealth = other.GetComponent<PlayerHealth>();
//给玩家加血
playerHealth.health += healthBonus;
//限制玩家的最大生命
playerHealth.health = Mathf.Clamp(playerHealth.health, 0f, 100f);
//更新血条
playerHealth.UpdateHealthBar();
pickupSpawner.StartCoroutine(pickupSpawner.DeliverPickup());
AudioSource.PlayClipAtPoint(collect,transform.position);
Destroy(transform.root.gameObject);
}
//如果碰到地面
else if(other.tag == "ground" && !landed)
{
anim.SetTrigger("Land");
transform.parent = null;
gameObject.AddComponent<Rigidbody2D>();
landed = true;
}
}
}
HealthPickup
using UnityEngine;
using System.Collections;
/// <summary>
/// 炸弹
/// </summary>
public class Bomb : MonoBehaviour
{
/// <summary>
/// 爆炸影响的半径
/// </summary>
public float bombRadius = 10f;
/// <summary>
/// 爆炸力
/// </summary>
public float bombForce = 100f;
/// <summary>
/// 爆炸声音
/// </summary>
public AudioClip boom;
/// <summary>
/// 炸弹引爆的声音
/// </summary>
public AudioClip fuse;
/// <summary>
/// 引爆持续时间
/// </summary>
public float fuseTime = 1.5f;
/// <summary>
/// 爆炸特效
/// </summary>
public GameObject explosion;
/// <summary>
/// 玩家放置炸弹
/// </summary>
private LayBombs layBombs;
/// <summary>
/// 收集物孵化器
/// </summary>
private PickupSpawner pickupSpawner;
/// <summary>
/// 爆炸粒子系统
/// </summary>
private ParticleSystem explosionFX;
void Awake ()
{
explosionFX = GameObject.FindGameObjectWithTag("ExplosionFX").GetComponent<ParticleSystem>();
pickupSpawner = GameObject.Find("pickupManager").GetComponent<PickupSpawner>();
if(GameObject.FindGameObjectWithTag("Player"))
layBombs = GameObject.FindGameObjectWithTag("Player").GetComponent<LayBombs>();
}
void Start ()
{
//如果炸弹没有父物体,说明炸弹已被放置,开始引爆
if(transform.root == transform)
StartCoroutine(BombDetonation());
}
/// <summary>
/// 炸弹引爆协程
/// </summary>
/// <returns></returns>
IEnumerator BombDetonation()
{
AudioSource.PlayClipAtPoint(fuse, transform.position);
yield return new WaitForSeconds(fuseTime);
Explode();
}
/// <summary>
/// 爆炸
/// </summary>
public void Explode()
{
//玩家可以放置炸弹
layBombs.bombLaid = false;
//开始新的投递
pickupSpawner.StartCoroutine(pickupSpawner.DeliverPickup());
//获取范围内的敌人
Collider2D[] enemies = Physics2D.OverlapCircleAll(transform.position, bombRadius, << LayerMask.NameToLayer("Enemies"));
foreach(Collider2D en in enemies)
{
Rigidbody2D rb = en.GetComponent<Rigidbody2D>();
if(rb != null && rb.tag == "Enemy")
{
//秒杀敌人
rb.gameObject.GetComponent<Enemy>().HP = ;
//将敌人推出一段距离
Vector3 deltaPos = rb.transform.position - transform.position;
Vector3 force = deltaPos.normalized * bombForce;
rb.AddForce(force);
}
}
//播放爆炸效果
explosionFX.transform.position = transform.position;
explosionFX.Play();
Instantiate(explosion,transform.position, Quaternion.identity);
AudioSource.PlayClipAtPoint(boom, transform.position);
Destroy (gameObject);
}
}
Bomb
using UnityEngine;
using System.Collections;
/// <summary>
/// 敌人
/// </summary>
public class Enemy : MonoBehaviour
{
/// <summary>
/// 移动速度
/// </summary>
public float moveSpeed = 2f;
/// <summary>
/// 玩家被击杀需要的次数
/// </summary>
;
/// <summary>
/// 死亡的动画
/// </summary>
public Sprite deadEnemy;
/// <summary>
/// 受到伤害的动画
/// </summary>
public Sprite damagedEnemy;
/// <summary>
/// 死亡声音
/// </summary>
public AudioClip[] deathClips;
/// <summary>
/// 敌人死亡后生成的 得分物体
/// </summary>
public GameObject hundredPointsUI;
/// <summary>
///
/// </summary>
public float deathSpinMin = -100f;
/// <summary>
///
/// </summary>
public float deathSpinMax = 100f;
/// <summary>
/// 精灵渲染器
/// </summary>
private SpriteRenderer ren;
/// <summary>
/// 检查前方的go
/// </summary>
private Transform frontCheck;
/// <summary>
/// 是否死亡
/// </summary>
private bool dead = false;
/// <summary>
/// 玩家得分脚本
/// </summary>
private Score score;
void Awake()
{
ren = transform.Find("body").GetComponent<SpriteRenderer>();
frontCheck = transform.Find("frontCheck").transform;
score = GameObject.Find("Score").GetComponent<Score>();
}
void FixedUpdate ()
{
//检测碰撞
Collider2D[] frontHits = Physics2D.OverlapPointAll(frontCheck.position, );
foreach(Collider2D c in frontHits)
{
//如果碰到障碍物
if(c.tag == "Obstacle")
{
//转向
Flip ();
break;
}
}
GetComponent<Rigidbody2D>().velocity = new Vector2(transform.localScale.x * moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
&& damagedEnemy != null)
ren.sprite = damagedEnemy;
&& !dead)
Death ();
}
/// <summary>
/// 受到伤害
/// </summary>
public void Hurt()
{
HP--;
}
void Death()
{
//关闭所有的精灵渲染器
SpriteRenderer[] otherRenderers = GetComponentsInChildren<SpriteRenderer>();
foreach(SpriteRenderer s in otherRenderers)
{
s.enabled = false;
}
//打开自身的渲染器,设置为死亡精灵
ren.enabled = true;
ren.sprite = deadEnemy;
//玩家得分+100
score.score += ;
//死亡标志位设为true
dead = true;
GetComponent<Rigidbody2D>().fixedAngle = false;
GetComponent<Rigidbody2D>().AddTorque(Random.Range(deathSpinMin,deathSpinMax));
//修改碰撞器为触发器
Collider2D[] cols = GetComponents<Collider2D>();
foreach(Collider2D c in cols)
{
c.isTrigger = true;
}
//播放随机的死亡声音
, deathClips.Length);
AudioSource.PlayClipAtPoint(deathClips[i], transform.position);
//实例化得分效果
Vector3 scorePos;
scorePos = transform.position;
scorePos.y += 1.5f;
Instantiate(hundredPointsUI, scorePos, Quaternion.identity);
}
/// <summary>
/// 转向
/// </summary>
public void Flip()
{
Vector3 enemyScale = transform.localScale;
enemyScale.x *= -;
transform.localScale = enemyScale;
}
}
Enemy
using UnityEngine;
using System.Collections;
/// <summary>
/// 移除器
/// </summary>
public class Remover : MonoBehaviour
{
/// <summary>
/// 水的飞溅效果
/// </summary>
public GameObject splash;
void OnTriggerEnter2D(Collider2D col)
{
//如果碰到玩家
if(col.gameObject.tag == "Player")
{
//禁用摄像机跟随玩家的脚本
GameObject.FindGameObjectWithTag("MainCamera").GetComponent<CameraFollow>().enabled = false;
//禁用玩家血条
if(GameObject.FindGameObjectWithTag("HealthBar").activeSelf)
{
GameObject.FindGameObjectWithTag("HealthBar").SetActive(false);
}
Instantiate(splash, col.transform.position, transform.rotation);
Destroy (col.gameObject);
StartCoroutine("ReloadGame");
}
else
{
Instantiate(splash, col.transform.position, transform.rotation);
Destroy (col.gameObject);
}
}
/// <summary>
/// 重新加载游戏协程
/// </summary>
/// <returns></returns>
IEnumerator ReloadGame()
{
);
Application.LoadLevel(Application.loadedLevel);
}
}
Remover
using UnityEngine;
using System.Collections;
/// <summary>
/// 玩家得分
/// </summary>
public class Score : MonoBehaviour
{
/// <summary>
/// 玩家得分
/// </summary>
;
/// <summary>
/// 玩家控制脚本
/// </summary>
private PlayerControl playerControl;
/// <summary>
/// 上一帧的得分
/// </summary>
;
void Awake ()
{
playerControl = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerControl>();
}
void Update ()
{
//设置得分文本
GetComponent<GUIText>().text = "Score: " + score;
//如果上一帧的得分不等与现在的得分
if(previousScore != score)
//播放嘲讽
playerControl.StartCoroutine(playerControl.Taunt());
//设置上一帧的额得分为 现在的得分
previousScore = score;
}
}
Score
using UnityEngine;
using System.Collections;
/// <summary>
/// 分数阴影
/// </summary>
public class ScoreShadow : MonoBehaviour
{
/// <summary>
/// Score Go
/// </summary>
public GameObject guiCopy;
void Awake()
{
//设置阴影的位置
Vector3 behindPos = transform.position;
behindPos = );
transform.position = behindPos;
}
void Update ()
{
GetComponent<GUIText>().text = guiCopy.GetComponent<GUIText>().text;
}
}
ScoreShadow
using UnityEngine;
using System.Collections;
/// <summary>
/// 暂停器
/// </summary>
public class Pauser : MonoBehaviour {
/// <summary>
/// 是否已暂停
/// </summary>
private bool paused = false;
void Update () {
if(Input.GetKeyUp(KeyCode.P))
{
paused = !paused;
}
if(paused)
Time.timeScale = ;
else
Time.timeScale = ;
}
}
Pauser
using UnityEngine;
using System.Collections;
/// <summary>
/// 并行背景
/// </summary>
public class BackgroundParallax : MonoBehaviour
{
/// <summary>
/// 并行背景数组
/// </summary>
public Transform[] backgrounds;
/// <summary>
///
/// </summary>
public float parallaxScale;
/// <summary>
///
/// </summary>
public float parallaxReductionFactor;
/// <summary>
///
/// </summary>
public float smoothing;
/// <summary>
/// 摄像机
/// </summary>
private Transform cam;
/// <summary>
/// 上一帧的相机位置
/// </summary>
private Vector3 previousCamPos;
void Awake ()
{
cam = Camera.main.transform;
}
void Start ()
{
previousCamPos = cam.position;
}
void Update ()
{
float parallax = (previousCamPos.x - cam.position.x) * parallaxScale;
; i < backgrounds.Length; i++)
{
);
Vector3 backgroundTargetPos = new Vector3(backgroundTargetPosX, backgrounds[i].position.y, backgrounds[i].position.z);
backgrounds[i].position = Vector3.Lerp(backgrounds[i].position, backgroundTargetPos, smoothing * Time.deltaTime);
}
previousCamPos = cam.position;
}
}
BackgroundParallax
using UnityEngine;
using System.Collections;
/// <summary>
/// 背景道具孵化器
/// </summary>
public class BackgroundPropSpawner : MonoBehaviour
{
/// <summary>
/// 背景道具的刚体
/// </summary>
public Rigidbody2D backgroundProp;
/// <summary>
/// 左侧的x轴孵化点
/// </summary>
public float leftSpawnPosX;
/// <summary>
/// 右侧的x轴孵化点
/// </summary>
public float rightSpawnPosX;
/// <summary>
///
/// </summary>
public float minSpawnPosY;
public float maxSpawnPosY;
/// <summary>
/// 最短的孵化时间间隔
/// </summary>
public float minTimeBetweenSpawns;
/// <summary>
/// 最长的孵化时间间隔
/// </summary>
public float maxTimeBetweenSpawns;
/// <summary>
/// 道具的最小速度
/// </summary>
public float minSpeed;
/// <summary>
/// 道具的最大速度
/// </summary>
public float maxSpeed;
void Start ()
{
//随机种子
Random.seed = System.DateTime.Today.Millisecond;
StartCoroutine("Spawn");
}
/// <summary>
/// 孵化协程
/// </summary>
/// <returns></returns>
IEnumerator Spawn ()
{
//随机等待时间
float waitTime = Random.Range(minTimeBetweenSpawns, maxTimeBetweenSpawns);
yield return new WaitForSeconds(waitTime);
//随机方向
,) == ;
float posX = facingLeft ? rightSpawnPosX : leftSpawnPosX;
//随机y轴位置
float posY = Random.Range(minSpawnPosY, maxSpawnPosY);
Vector3 spawnPos = new Vector3(posX, posY, transform.position.z);
Rigidbody2D propInstance = Instantiate(backgroundProp, spawnPos, Quaternion.identity) as Rigidbody2D;
if(!facingLeft)
{
Vector3 scale = propInstance.transform.localScale;
scale.x *= -;
propInstance.transform.localScale = scale;
}
//随机速度
float speed = Random.Range(minSpeed, maxSpeed);
speed *= facingLeft ? -1f : 1f;
propInstance.velocity = );
//重新孵化
StartCoroutine(Spawn());
while(propInstance != null)
{
if(facingLeft)
{
if(propInstance.transform.position.x < leftSpawnPosX - 0.5f)
Destroy(propInstance.gameObject);
}
else
{
if(propInstance.transform.position.x > rightSpawnPosX + 0.5f)
Destroy(propInstance.gameObject);
}
yield return null;
}
}
}
BackgroundPropSpawner
using UnityEngine;
using System.Collections;
/// <summary>
/// 摄像机跟随玩家
/// </summary>
public class CameraFollow : MonoBehaviour
{
public float xMargin = 1f;
public float yMargin = 1f;
public float xSmooth = 8f;
public float ySmooth = 8f;
public Vector2 maxXAndY;
public Vector2 minXAndY;
private Transform player;
void Awake ()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
}
bool CheckXMargin()
{
return Mathf.Abs(transform.position.x - player.position.x) > xMargin;
}
bool CheckYMargin()
{
return Mathf.Abs(transform.position.y - player.position.y) > yMargin;
}
void FixedUpdate ()
{
TrackPlayer();
}
void TrackPlayer ()
{
float targetX = transform.position.x;
float targetY = transform.position.y;
if(CheckXMargin())
targetX = Mathf.Lerp(transform.position.x, player.position.x, xSmooth * Time.deltaTime);
if(CheckYMargin())
targetY = Mathf.Lerp(transform.position.y, player.position.y, ySmooth * Time.deltaTime);
targetX = Mathf.Clamp(targetX, minXAndY.x, maxXAndY.x);
targetY = Mathf.Clamp(targetY, minXAndY.y, maxXAndY.y);
transform.position = new Vector3(targetX, targetY, transform.position.z);
}
}
CameraFollow
using UnityEngine;
using System.Collections;
/// <summary>
/// 设置粒子系统的SortingLayer
/// </summary>
public class SetParticleSortingLayer : MonoBehaviour
{
/// <summary>
/// SortingLayer名
/// </summary>
public string sortingLayerName;
void Start ()
{
//设置粒子系统的sortingLayer名
GetComponent<ParticleSystem>().GetComponent<Renderer>().sortingLayerName = sortingLayerName;
}
}
SetParticleSortingLayer
视频:https://pan.baidu.com/s/1skBrKnF
项目:https://pan.baidu.com/s/1qXDvBWg
2D Platformer 学习的更多相关文章
- Cocos 2d TestCPP 学习
Cocos 2d testcpp包含了大量的demo, 对于新手学习cocos引擎具有非常大的帮助.因为接下来的开发项目有可能会用到该引擎,所以希望可以利用自己的业余时间提前熟悉起来.该篇文章会记录自 ...
- [Unity] 2D开发学习教程
豆子先生,据说是官方的一个Demo, 在蛮牛网上有大部分代码的视频讲解. 这个是我学习过程中边看教程边写出来的,功能和原版基本一样,增加了手游的操控. Blog: http://www.cnblogs ...
- u3d 2D开发学习
http://gad.qq.com/article/detail/45365 https://blog.csdn.net/s556699/article/details/55224830 UI层设计 ...
- Android 2D Graphics学习 Region和Canvas裁剪
1.首先介绍Region类 Region,中文意思即区域的意思,它表示的是canvas图层上的某一块封闭的区域. /**构造方法*/ public Region() //创建一个空的区域 publi ...
- 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...
- Unity 官方教程 学习
Interface & Essentials Using the Unity Interface 1.Interface Overview https://unity3d.com/cn/lea ...
- Quartz 2D编程指南(1) - 概览
Quartz 2D编程指南是论坛会员德鲁伊翻译的国外的Quartz 2D一系列学习资料,供大家参考 Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境.我们可以使用Quar ...
- 【转】通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 引子 在第一篇文章[Unity3D基础教程] ...
- Android UI开发第四十二篇——实现实现易信的圆形图像和对话列表的图像显示部分
显示图像时,很多个性化显示,圆形或圆角.气泡等等,我们这一篇文章探讨一下圆形和气泡的显示,仿照易信中的实现,先看下效果图: 代码: public class RoundImageView extend ...
随机推荐
- VSTO:使用C#开发Excel、Word【7】
第2章Office解决方案介绍 Office解决方案的三种基本模式现在,您了解Office对象模型的基本模式,本章将介绍开发人员如何模拟和构建其Offi ...
- sas 选择一段日期,和一定周期,生成日期序列和周期序列
工作需要,得选择一段日期,和一定周期,生成日期序列和周期序列.暂时用七天为一个周期 data d; format date date9.; do date='04mar2018'd to'05may2 ...
- 完全卸载vs2013 2015
/uninstall /force 解压你的vs2013的安装包(iso格式). cd到解压后的文件夹 vs_ultimate.exe /uninstall /force 或者创建一个快捷方式到桌面 ...
- BootstrapValidator验证
相关链接: https://www.cnblogs.com/wuwenshuai/p/7120755.html https://www.cnblogs.com/v-weiwang/p/4834672. ...
- FFT理解
*连续时间-周期性信号频谱 clc;clear;close all N = input('N= '); T = 0.05; n = 1:N; %原始数据输入 D = 2*pi/(N*T); %计算分 ...
- page指令import属性实例
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...
- Android开发 ---基本UI组件3:单选按钮、多选按钮、下拉列表、提交按钮、重置按钮、取消按钮
Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个用户注册按钮 <?xml version="1.0" encoding=&q ...
- it网站
1:http://www.importnew.com/ importnew 专注于java的论坛 2:Github是最活跃的开源代码库和版本控制平台,可以说是程序员当中知名度最高的技术社区.各 ...
- mysql储存引擎
Mysql数据库常用存储引擎 数据库存储引擎:是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建.查询.更新和删除数据.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使 ...
- linux 基本命令大全
系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...