UNITY Main camera360 看不见sprites

unity果冻精灵 Jelly Sprites 1.36,Unity3D,游戏源码,6m5m游戏素材
请求处理中...
unity果冻精灵 Jelly Sprites 1.36Requires Unity 4.6.2 or& higher.Add dynamic soft body style physics to any sprite in your game! Jelly Sprites allows you to quickly and easily convert boring static sprites into ones that will bounce, stretch and deform, naturally reacting to physical forces from your game.&* Works with Unity and 2D Toolkit sprites.* Supports both 2D and 3D physics systems.* Simple to configure, but with in-depth configuration options to let you easily balance quality and performance.* Quickly create sprites with rectangular, circular, triangluar and grid body configurations.* Convert any Jelly Sprite to 'Free' mode in order to directly move and scale rigid bodies in the Scene View.* 'Attach Point' system allows child ob jects to react to physics forces just like the main Jelly Sprite.* Full C# source code and example scene included.&
或 0 积分 ()
下载92浏览人数1033交付方式直接下载
免责声明:【1】资源来自网络,仅限于个人学习研究,请勿用于任何商业用途,请支持或购买正版,尊重版权,请严格遵守国家相关著作版权保护的法律和规则,请下载24小时内务必删除,否则后果自负,本站不承担任何责任及连带责任!【2】本站为学习平台,所分享的资源以学习为目的,并不能保证所有源码人人都能编译,因素太多,旨在学习参考,无任何技术支持,如果您要求完美或追求细节,请勿下载,大家都不容易,互相理解,才能让更多好的学习资源出现!【3】部分素材压缩包因体积过大而上传到百度等网盘上,如果发现在本站下载的压缩包只要有几K大小,说明该压缩包里只是网盘的下载链接,并非文件损坏,本站的所有素材都是经过了审核,大家可放心下载,欢迎监督反馈。【4】做个好平台真心不容易,我们一直在努力,因本站素材量大,难免会出现某网盘下载链接失效等问题,请大家及时反馈,我们会及时修正保证您可以拿到素材,请大家支持和理解!
免责声明:本网所展示的素材与服务信息由买卖双方自行提供,其真实性、准确性和合法性由信息发布人负责。本网不提供任何保证,并不承担任何法律责任,如有不妥之处请及时反馈,本网将会妥善处理。
友情提醒:本站旨在游戏开发的学习,所分享的素材资源均来源于网络,仅适用于学习参考,尊重版权,禁止用于任何商业用途,否则后果自负,所展示的素材版权归原作者或公司所有,如果本站素材侵犯了您的权益,请联系我们,我们将及时处理。
猜您喜欢的游戏素材
0金币 / 份
1金币 / 个
1金币 / 个
0金币 / 个
1金币 / 个
0金币 / 个
0金币 / 个
2金币 / 个
0金币 / 个
1金币 / 个
发布素材40sprite - Unity Answers
Navigation
Unity account
You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio.
10 RepliesSiki_Unity_1-9_Unity2D游戏开发_Roguelike拾荒者 - FudgeBear - 博客园
Unity 1-9 Unity2D游戏开发 Roguelike拾荒者
任务1:游戏介绍
Food:相当于血量:每走一步下降1,吃东西可以回复(果子10药水20),被怪物攻击会减少中间的障碍物可以打破,人走两步僵尸走一步;走到Exit进入下一关
最外圈的过道会保证是空的,其他的随机生成(--确保主角能够到达出口)
任务2:创建工程、素材
pan.baidu.com/s/1kTYS8ez
Unity5.2.1
2D Project -- Roguelike  导入Assets.unitypackage
Sprites-&所有切好的图片 -- 主角/地形/出口/围墙/僵尸等
任务3:创建游戏主角
Sprites中找到6个主角Scavengers的sprite图片,拖入Hierachy中  会自动在游戏物体Scavengers_SpritesSheet_0中创建一个动画Animator,并将Animation  和AnimationController保存在Sprites文件夹中,重命名控制器为Player/ 动画为PlayerIdle  并创建文件夹分类Assets-&Animations-&Animation/AnimatorController
此时,运行游戏,会自动播放Idle动画
双击AnimatorController打开动画编辑器,修改速度为0.5
创建攻击动画:  将两个攻击Sprites拖入Player物体,会自动在Player中创建一个新的动画PlayerAttack
创建受攻击动画:相似 -- PlayerUnderAttack
创建主角的Prefab
任务4:创建敌人
与创建主角相似
创建完Enemy1,创建Enemy1的Prefab
因为Enemy2的动画控制器AnimatorController与Enemy1相同  在Project视窗中右键Create-&Animator Override Controller  将Enemy1的Animator赋值给新建的Animator -- 表示两个Enemy共用一个状态机  将Hierarchy中的Enemy1-&GameObject-&Break prefab instance,重命名为Enemy2  将Enemy2 Animator赋值给Enemy2  创建Enemy2的两个动画,将动画拖入Enemy2 Animator赋值即可
相当于:Enemy1和Enemy2共用了Enemy1的状态机(Animator),但是使用了不同动画
创建Enemy2的Prefab
任务5:创建地板/ 围墙/ 食物
创建地板:
把8种地板和出口分别拖入,并重命名Floor1~8/ Exit
把8中障碍物拖入,重命名为Wall1~8
做成Prefab&
创建围墙:三种围墙,重命名为OutWall1~3并做成Prefab
创建食物:拖入Soda和Food,做成Prefab
任务6:生成地图
创建空物体GameManager
创建MapManager.cs  // 地图左下角设置为(0, 0)  public GameObject[] outWallArray/ floorA  // 创建根物体  private Transform mapH  mapHolder = new GameObject("Map").
  // 初始化围墙  for x for y(...) {    GameO    if (x==0 || y==0 || x==cols-1 || y==rows-1) {      int index = Random.Range(0, outWallArray.Length);      cell = GameObject.Instantiate        (outWallArray[index], ...(x, y, 0), Quaternion.identity) as GameO      // as GameObject -- .Instantiate()生成的为Object类型,强制转化为GameObject      // 在(x,y,0)处生成一个旋转为0的围墙    } else ...    cell.transform.SetParent(mapHolder);  }
  // 初始化地板  else {    int index = Random.Range(0, floorArray.Length);    cell = GameObject.Instantiate      (floorArray[index], ...(x,y,0), Quaternion.identity) as GameO  }
此时生成的地图并不位于相机正中心  -- 地图长10宽10 -- (每一格长宽为1,从(0,0)开始,即画面从(-0.5, -0.5开始))  --& Camera位置:(4.5, 4.5, 0),颜色改为黑色
private void InitMap() {
for (int x = <span style="color: #; x & x++) {
for (int y = <span style="color: #; y & y++) {
if (x == <span style="color: # || x == cols - <span style="color: # || y == <span style="color: # || y == rows - <span style="color: #) {
int index = Random.Range(<span style="color: #, outWallArray.Length);
cell = GameObject.Instantiate
(outWallArray[index], new Vector3(x, y, <span style="color: #), Quaternion.identity);
int index = Random.Range(<span style="color: #, floorArray.Length);
cell = GameObject.Instantiate
(floorArray[index], new Vector3(x, y, <span style="color: #), Quaternion.identity);
cell.transform.SetParent(mapHolder);
任务7:控制障碍物的生成
在InitMap()中
private List&Vector2& positionList = new List&Vector2&(); // 用于取得中间部分的格子位置
positionList.Clear();
for(int x/y = 0 + 2; x/y & cols/rows - 2; x/y++) {& // 围墙一列,空道一列  positionList.Add(new Vector2(x, y));}
// 从上面的positionList中随机取得格子放入障碍物/食物/敌人// 创建障碍物public GameObject[] wallArray;public int min/maxCountWall = 2/8;int wallCount = Random.Range(minCountWall, maxCountWall + 1);for(int i = 0~wallCount) {  // 随机取得格子位置  int positionIndex = Random.Range(0, positionList.Count); // 随机取得index  Vector2 pos = positionList[positionIndex]; // 得到位置信息  positionList.RemoveAt[positionIndex]; // 移除该位置 -- 保证一个格子只能有一个东西  // 随机取得障碍物  int wallIndex = Random.Range(0, wallArray.Length);  GameObject cell = GameObject(wallArray[...], pos, ...) as GameO  cell.transform.SetParent(mapHolder);}
避免地板将障碍物覆盖,设置Layer:Background/ Items/ Roles
positionList = new List&Vector2&();
positionList.Clear();
for(int x = <span style="color: #+<span style="color: #; x & cols - <span style="color: #; x++) {
for(int y = <span style="color: # + <span style="color: #; y & rows - <span style="color: #; y++) {
positionList.Add(new Vector2(x, y));
int wallCount = Random.Range(minCountWall, maxCountWall + <span style="color: #);
for(int i = <span style="color: #; i & wallC i++) {
int positionIndex = Random.Range(<span style="color: #, positionList.Count);
Vector2 pos = positionList[positionIndex];
positionList.RemoveAt(positionIndex);
int wallIndex = Random.Range(<span style="color: #, wallArray.Length);
GameObject cell = GameObject.Instantiate
(wallArray[wallIndex], pos, Quaternion.identity) as GameO
cell.transform.SetParent(mapHolder);
任务8&9:敌人和食物的随机生成 & 代码优化
食物和敌人的数量与关卡有关 -- 数量成正比
创建GameManager.cs -- 控制游戏关卡  public int level = 1;
在MapManager.cs中  // 获取GameManager  private GameManager gameM  gameManager = GetComponent&GameManager&();
创建食物 -- 数量2~level*2  int foodCount = Random.Range(2, gameManager.level * 2 + 1);  // 取得随机位置 -- 重复代码写成Vector2 RandomPosition()  Vector2 pos = RandomPosition();  // 随机取得物体 -- 重复代码写成GameObject RandomPrefab(GameObject[] prefabs);  GameObject foodPrefab= Instantiate(RandomPrefab(foodArray)) as GameO  foodPrefab.transform.setParent(mapHolder);
// get a random available position
private Vector2 RandomPosition() {
int positionIndex = Random.Range(<span style="color: #, positionList.Count);
Vector2 pos = positionList[positionIndex];
positionList.RemoveAt(positionIndex);
// get a random gameobject
private GameObject RandomPrefab(GameObject[] prefabs) {
int index = Random.Range(<span style="color: #, prefabs.Length);
return prefabs[index];
创建敌人 -- 数量为level / 2  int enemyCount = gameManager.level/2;  for(0~enemyCount) {    Vector2 pos = ...;    GameObject enemyPrefab = GameObject.Instantiate(...) as GameO    enemyPrefab.transform.setParent(mapHolder);  }
创建出口 -- 位置固定在右上方  GameObject exit =     (Instantiate(exitPrefab, new Vector2(cols-2, rows-2), Quaternion.identity) as GameO  exti.transform.SetParent(mapHolder);
-- 代码优化
上面的创建代码是可重用的 -- 写成method
private void InstantiateItems(int count, GameObject[] itemArray) {
for(int i = <span style="color: #; i & i++) {
GameObject item = GameObject.Instantiate(RandomPrefab
(itemArray), RandomPosition(), Quaternion.identity) as GameO
item.transform.SetParent(mapHolder);
任务10:完善主角和敌人的动画状态机
Player的动画:PlayerIdle/ PlayerUnderAttack/ PlayerAttack
PlayerIdle&--&PlayerUnderAttackPlayerIdle&--&PlayerAttack
在Animator中添加触发器Trigger分别称为Damage和Attack
Idle-&Attack/UnderAttack:  将Has Exit Time取消勾选 -- 在Idle动画的任何时候都可以随时切换到另一个动画  Transition Duration = 0 -- 因为这里的动画是帧动画,因此可以进行瞬时切换成其他动画  Conditions 切换方式:添加Attack/Damage Trigger
拖动左边的箭头可以手动播放动画;拖动右边的两个箭头可以手动控制何时切换
Attack/UnderAttack-&Idle:  勾选Has Exit Time即可 -- 播放完Attack/UnderAttack后自动切换到Idle动画  Transition Duration = 0 -- 瞬时间切换  Exit Time = 1 -- 退出时间(多久进行切换)
Enemy的动画:EnemyIdle/ EnemyAttack
Idle-&Attack:  添加触发器Attack  Has Exit Time uncheck  Transition Duration = 0
Attack-&Idle:  Has Exit Time check  Exit Time = 1  Transistion Duration = 0
检测动画:
运行游戏;选中Player/ Enemy;在Animator视窗中查看状态机
点击Trigger右边的小圆点,即为触发该Trigger
任务11:控制主角的运动
为Player添加刚体,用于控制移动,勾选Is Kinematic
为Player添加BoxCollider2D,用于检测碰撞(大小不能设置为(1,1),0.9就好)
为Player添加Player.cs来控制移动  private int posx/posy = 1; // 当前位置  private int Vector2 targetPos = new Vector2(1,1); // 目标位置
  float h/v = Input.GetAxisRaw("Horizontal"/"Vertical"); // GetAxisRaw()的返回值为-1/0/1  targetPos += new Vector2(h,v); // 按键后,目标位置发生改变  private Rigidbody2D rigidbody = GetComponent&Rigidbody2D&(); // 得到刚体,用于移动  rigidbody.MovePosition(Vector2.Lerp(transform.position, targetPos, smoothing*Time.deltaTime));     // MovePosition(目标位置):向目标位置移动    // Lerp(起点,终点,速度);这里设smoothing=1
发现此时按下按钮会移动很长的距离 -- Update中不停调用targetPos += Vector2();&
需要设置一个休息时间:  public float restTime = 0.5f;  public float restTimer = 0.5f; // 计时器
在Update()中  restTimer += Time.deltaT // 每次增加时间间隔  if(restTimer &= restTime) { // 还在休息间隔中     // 不进行其他操作  }
  当有按键按下时:  if(h!=0 || v!=0) {    targetPos += ...; // 更新目标位置    rigidbody.MovePosition(...); // 移动    restTimer = 0; // 重置计时器  }
按下按键时,只能移动一点点距离  将rigidbody.MovePosition()代码移出if条件  因为每一帧都需要调用而不是只有按键的时候调用
发现可以一次同时在水平和竖直移动 -- 和游戏规则有悖  if(h!=0) v=0; // 优先控制竖直方向
void Update () {
rigidbody.MovePosition(Vector2.Lerp(transform.position, targetPos, smooth * Time.deltaTime));
if (restTimer & restTime) {
restTimer += Time.deltaT
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
if (h != <span style="color: #) {
v = <span style="color: #;
if (h != <span style="color: # || v != <span style="color: #) {
// 有按键输入时
targetPos += new Vector2(h, v);
restTimer = <span style="color: #; // 计时器归零
任务12:控制主角对墙体的攻击
给outWall添加BoxCollider2D,scale=0.9;添加tag = OutWall
给wall添加BoxCollider2D,scale=0.9;添加tag = Wall
在每次按键的时候,进行碰撞检测:  RaycastHit2D hit = Physics2D.Linecast(targetPos, targetPos + new Vector2(h, v));     // Physics2D.Linecast(起点,终点) 从起点向终点发射射线做检测,返回RaycastHit2D  if(hit.transform == null) { // 没有碰撞,可以行走  } else { // 有碰撞    switch(hit.collider.tag) {      case "OutWall": // 不做处理      case "Wall": // 进行攻击        // 向墙发送攻击的通知        // 在Wall里添加Wall.cs来处理行为 Wall.TakeDamage();        hit.collider.SendMessage("TakeDamage");
public int hp = <span style="color: #;
public Sprite damageS // 受损后的墙体图片
public void TakeDamage() {
hp -= <span style="color: #;
GetComponent&SpriteRenderer&().sprite = damageS
if(hp&=<span style="color: #) Destroy(this.gameObject);
禁用自身的collider,因为可能射线会碰到自身的collider:  private BoxCollider2D collider = GetComponent&...&();  collider.enabled =  ... // 射线检测  collider.enabled = // 检测后再启用
无论是移动还是攻击,都需要休息 -- 只要按下了按键,restTimer = 0;
攻击时,播放PlayerAttack动画  Player.cs    private Animator animator = GetComponent&Animator&();    animator.SetTrigger("Attack"); // 触发触发器
rigidbody.MovePosition(
Vector2.Lerp(transform.position, targetPos, smooth * Time.deltaTime));
if (restTimer & restTime) {
restTimer += Time.deltaT
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
if (h != <span style="color: #) {v = <span style="color: #;}
if (h != <span style="color: # || v != <span style="color: #) {
// 有按键输入时
collider.enabled = false; // 禁用自身collider
// 碰撞检测
RaycastHit2D hit =
Physics2D.Linecast(targetPos, targetPos + new Vector2(h, v));
if (hit.transform == null) {
// 没有检测到碰撞
targetPos += new Vector2(h, v);
// 检测到碰撞
switch (hit.collider.tag) {
case "OutWall":
case "Wall":
hit.collider.SendMessage("TakeDamage");
animator.SetTrigger("Attack");
restTimer = <span style="color: #; // 计时器归零
collider.enabled = true; // 检测完碰撞后 开启自身collider
任务13:控制主角吃食物
对食物进行碰撞检测:
对食物添加BoxCollider2D;设置为Is Trigger,scale=0.9,tag=food
存储当前食物 GameManager.public int food = 100;  将GameManager设置为单例模式
private static GameManager _
public static GameManager Instance {
private void Awake() {
_instance = this;
增加/减少食物的method:public void Add/ReduceFood(int count)  food +=/-=
case "Food":  // 用if判断hit.collider.name是Food(Clone)还是Soda(Clone)  GameManager.Instance.AddFood(10 | 20);  // 同时,需要移动Player位置 && 销毁食物  targetPos += new Vector2(h, v);  Destroy(hit.collider.gameObject);
case "Food":
targetPos += new Vector2(h, v);
Destroy(hit.collider.gameObject);
if (hit.collider.name == "Food(Clone)") {
GameManager.Instance.AddFood(<span style="color: #);
} else if(hit.collider.name == "Soda(Clone)") {
GameManager.Instance.AddFood(<span style="color: #);
任务14&15:控制敌人的移动
当Player移动两步时,敌人移动一步
给Enemy添加BoxCollider2D进行碰撞检测,size=0.9,&
给Enemy添加Rigidbody2D进行移动,勾选Is Kinematic:很重要  如果没有勾选,会导致后面Enemy被Player推走
给Enemy添加tag=Enemy
case "Enemy": // 说明所走的路径不通,判断失误,浪费一步  &
给Enemy添加Enemy.cs  Enemy是被动移动 -- 提供移动方法,供其他对象调用  public void Move() {    // 判断Player所在位置的方向    // Transform player = GameObject.FindGameObjectWithTag(...)&    Vector2 offset = player.position - transform.    if (offset.magnitude & 1.9f) { // 距离小于一格      // 攻击    } else { // 追 -- 哪个轴偏移大,就往哪里追      if (Mathf.Abs(offset.x) & Mathf.Abs(offset.y)) { // x轴移动        if(offset.x&0) x=-1; else x=1;      } else { // y轴移动        if(offset.y&0) y=-1;&else y=1;      }      targetPos += new Vector(x, y);    }
在GameManager.cs中统一管理游戏进程:  public List&Enemy& enemyList = new List...;
在Enemy.cs中:  GameManager.Instance.enemyList.Add(this);
在GameManager.cs中控制Enemy是否行走:  bool sleepStep = // 是否为休息状态  OnPlayerMove() {    if(sleepStep) sleepStep =    else { foreach enemy in enemyList { enemy.Move();       sleepStep = }  }
在Player.cs中  有按键按下的时候调用OnPlayerMove()  GameManager.Instance.OnPlayerMove();
此时,Enemy会随着主角移动而移动,但是Enmey没有碰撞检测
设置目标位置targetPos之前先做检测
// 更新位置之前,做碰撞检测
collider.enabled = false; // 否则会碰撞到自己的collider
RaycastHit2D hit = Physics2D.Linecast(targetPos, targetPos+new Vector2(x,y));
collider.enabled = true;
if (hit.collider == null) {
// 没有碰撞
targetPos += new Vector2(x, y);
switch (hit.collider.tag)
case "Wall":
case "OutWall": // 不可能出现外墙的情况
case "Food":
Destroy(hit.collider.gameObject);
targetPos += new Vector2(x, y);
任务16:控制敌人的攻击
private Animator animator = GetComponent&...&();animator.SetTrigger("Attack");player.SendMessage("TakeDamage", lossFood);& // 不同敌人的伤害不同
public void TakeDamage(int lossFood) {  GameManager.Instance.ReduceFood(lossFood);  animator.SetTrigger("UnderAttack");&}
任务17:控制游戏食物数量UI的显示
在Player每走一步就消耗一定量食物:  GameManager.Instance.ReduceFood(1);
在屏幕上显示食物:  右键创建UI-&Text,重命名FoodText  字体剧中,字号25,字体为Font-&PressStart2P-Regular,内容:Food: 100  放置在屏幕下方,Anchor Presets设置为bottom-center
在GameManager.cs中控制UI的更新  private Text foodT  在void Awake()中&加入 InitGame();    void InitGame() {       foodText = GameObject.Find("FoodText").GetComponent...;&       UpdateFoodText(0);    }
private void UpdateFoodText(int foodChange) {
if (foodChange == <span style="color: #) {
foodText.text = "Food: " +
} else if (foodChange & <span style="color: #) {
foodText.text = "+" + foodChange + "
foodText.text = foodChange + "
在ReduceFood()/ AddFood(){}&中加上 UpdateFoodText(count/-count);
任务18:控制游戏的失败  
游戏失败:Food &= 0;  Player每走完一步:检测food的数量  --&我的优化:在GameManager中的ReduceFood()中检测 --&没有必要每一步都检测
  if(food&=0){&    GameObject.FindGameObjectWithTag("Player").SetActive(false);&     //&显示游戏失败 -- UI-&Text,居中,白色,字号,字体,GameOver等等    gameOverText.enabled =  }
任务19&20:游戏关卡的胜利判断 && 下一关卡的加载
判断Player是否到达了Exit的位置(8,8)
每次Player移动,判断是否到达终点  Player每次移动,都会调用GameManager中的OnPlayerMove()  在OnPlayerMove()中加入    //&需要得到player的targetPos,与destinationPos比较    将targetPos改为[HideInInspector]public targetP    Player player = GameObject.Find...Tag(...).GetComponent...;    // 还需得到Exit的位置    MapManager mapManager = GetComponent...;    if(player.targetPos.x == mapManager.cols-2 && ...y==rows-2) {      private bool missionCompleted =      //&加载下一关卡      Application.LoadLevel(Application.loadedLevel); // 重新加载本关卡 --&已弃用      SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);&      // 需要记住某些值 -- 使用系统函数OnLevelWasLoaded()&    }
运行 -- 发现可以重置关卡了,但是所有数据会重置
GameManager实例不能销毁 -- 否则数据会重置  在GameManager.cs的Awake()中:
    DontDestroyOnLoad(gameObject);
运行 -- 发现原来的GameManager没有销毁,但是新建了另一个GameManager
不将GameManager放在场景中  --&将GameManager做成Prefab  -- 删除场景中的GameManager  在MainCamera中添加GameLoader.cs
// 实例化GameManager
public GameObject gameM
void Awake() {
if(GameManager.Instance == null) {
GameObject.Instantiate(gameManager);
任务21:控制天数UI的显示
当前天数的显示  UI-&Image-&DayI alt+上下左右居中;颜色设置为黑色  在DayImage中创建一个Text叫DayText;居中偏上;字号32;字体自定义;颜色白色
什么时候显示呢? -- 初始化UI的时候需要显示
GameManage.InitGame()中:  private Image dayImage = GameObject.Find("DayImage").GetComponent&Image&();  private Text dayText ...;  dayText.text = "Day " +
显示完天数,需要隐藏
void HideDayImage() {
dayImage.gameObject.SetActive(false);
在InitGame()最后调用 Invoke("HideDayImage", 1);&即可& --&过1s后调用
任务22:添加音效
GameManager.cs}

我要回帖

更多关于 cameraraw 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信