当前位置: 首页 > news >正文

莆田建设信息网站优化设计三要素

莆田建设信息网站,优化设计三要素,学校网站的建设,官渡网站建设提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、通过InControl插件实现绑定玩家输入二、制作小骑士移动和空闲动画 1.制作动画2.玩家移动和翻转图像3.状态机思想实现动画切换总结 前言 好久没来CSDN看看&…

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、通过InControl插件实现绑定玩家输入
  • 二、制作小骑士移动和空闲动画
    • 1.制作动画
    • 2.玩家移动和翻转图像
    • 3.状态机思想实现动画切换
  • 总结


前言

好久没来CSDN看看,突然看到前两年自己写的文章从零开始制作空洞骑士只做了一篇就突然烂尾了,刚好最近开始学习做Unity,我决定重启这个项目,从零开始制作空洞骑士!第一集我们导入了素材和远程git管理项目,OK这期我们就从通过InControl插件实现绑定玩家输入以及制作小骑士移动和空闲动画。


一、通过InControl插件实现绑定玩家输入

其实这一部挺难的,因为InControl插件你在网上绝对不超过五个视频资料,但没办法空洞骑士就是用这个来控制键盘控制器输入的,为了原汁原味就只能翻一下InControl提供的Examples示例里学习。

学习完成后直接来看我写的InputHandler.cs和GameManager.cs

在GameManager.cs中我们暂且先只用实现一个单例模式:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GameManager : MonoBehaviour
{private static GameManager _instance;public static GameManager instance{get{if(_instance == null){_instance = FindObjectOfType<GameManager>();}if (_instance == null){Debug.LogError("Couldn't find a Game Manager, make sure one exists in the scene.");}else if (Application.isPlaying){DontDestroyOnLoad(_instance.gameObject);}return _instance;}}private void Awake(){if(_instance != this){_instance = this;DontDestroyOnLoad(this);return;}if(this != _instance){Destroy(gameObject);return;}}}

 在来到InputHandler.cs之前,我们还需要创建映射表HeroActions:

using System;
using InControl;public class HeroActions : PlayerActionSet
{public PlayerAction left;public PlayerAction right;public PlayerAction up;public PlayerAction down;public PlayerTwoAxisAction moveVector;public HeroActions(){left = CreatePlayerAction("Left");left.StateThreshold = 0.3f;right = CreatePlayerAction("Right");right.StateThreshold = 0.3f;up = CreatePlayerAction("Up");up.StateThreshold = 0.3f;down = CreatePlayerAction("Down");down.StateThreshold = 0.3f;moveVector = CreateTwoAxisPlayerAction(left, right, up, down);moveVector.LowerDeadZone = 0.15f;moveVector.UpperDeadZone = 0.95f;}
}

OK到了最关键的InputHandler.cs了:

using System;
using System.Collections;
using System.Collections.Generic;
using GlobalEnums;
using InControl;
using UnityEngine;public class InputHandler : MonoBehaviour
{public InputDevice gameController;public HeroActions inputActions;public void Awake(){inputActions = new HeroActions();}public void Start(){MapKeyboardLayoutFromGameSettings();if(InputManager.ActiveDevice != null && InputManager.ActiveDevice.IsAttached){}else{gameController = InputDevice.Null;}Debug.LogFormat("Input Device set to {0}.", new object[]{gameController.Name});}
//暂时没有GameSettings后续会创建的,这里是指将键盘按键绑定到HeroActions 中private void MapKeyboardLayoutFromGameSettings(){AddKeyBinding(inputActions.up, "W");AddKeyBinding(inputActions.down, "S");AddKeyBinding(inputActions.left, "A");AddKeyBinding(inputActions.right, "D");}private static void AddKeyBinding(PlayerAction action, string savedBinding){Mouse mouse = Mouse.None;Key key;if (!Enum.TryParse(savedBinding, out key) && !Enum.TryParse(savedBinding, out mouse)){return;}if (mouse != Mouse.None){action.AddBinding(new MouseBindingSource(mouse));return;}action.AddBinding(new KeyBindingSource(new Key[]{key}));}}
 给我们的小骑士创建一个HeroController.cs,检测输入最关键的是一行代码:
move_input = inputHandler.inputActions.moveVector.Vector.x;
using System;
using System.Collections;
using System.Collections.Generic;
using HutongGames.PlayMaker;
using GlobalEnums;
using UnityEngine;public class HeroController : MonoBehaviour
{public ActorStates hero_state;public ActorStates prev_hero_state;public bool acceptingInput = true;public float move_input;public float RUN_SPEED = 5f;private Rigidbody2D rb2d;private BoxCollider2D col2d;private GameManager gm;private InputHandler inputHandler;private void Awake(){SetupGameRefs();}private void SetupGameRefs(){rb2d = GetComponent<Rigidbody2D>();col2d = GetComponent<BoxCollider2D>();gm = GameManager.instance;inputHandler = gm.GetComponent<InputHandler>();}void Start(){}void Update(){orig_Update();}private void orig_Update(){if (hero_state == ActorStates.no_input){}else if(hero_state != ActorStates.no_input){LookForInput();}}private void FixedUpdate(){if (hero_state != ActorStates.no_input){Move(move_input);}}private void Move(float move_direction){if(acceptingInput){rb2d.velocity = new Vector2(move_direction * RUN_SPEED, rb2d.velocity.y);}}private void LookForInput(){if (acceptingInput){move_input = inputHandler.inputActions.moveVector.Vector.x;}}
}[Serializable]
public class HeroControllerStates
{public bool facingRight;public bool onGround;public HeroControllerStates(){facingRight = true;onGround = false;}
}

记得一句话:FixedUpdate()处理物理移动,Update()处理逻辑 

二、制作小骑士移动和空闲动画

1.制作动画

        素材找到Idle和Walk文件夹,创建两个同名animation,sprite往上面一放自己就做好了。

        可能你注意到我没有给这两个动画连线,其实是我想做个动画状态机,通过核心代码

        animator.Play()来管理动画的切换。

2.玩家移动和翻转图像

我们还需要给小骑士添加更多的功能比如翻转图像:

using System;
using System.Collections;
using System.Collections.Generic;
using HutongGames.PlayMaker;
using GlobalEnums;
using UnityEngine;public class HeroController : MonoBehaviour
{public ActorStates hero_state;public ActorStates prev_hero_state;public bool acceptingInput = true;public float move_input;public float RUN_SPEED = 5f;private Rigidbody2D rb2d;private BoxCollider2D col2d;private GameManager gm;private InputHandler inputHandler;public HeroControllerStates cState;private HeroAnimatorController animCtrl;private void Awake(){SetupGameRefs();}private void SetupGameRefs(){if (cState == null)cState = new HeroControllerStates();rb2d = GetComponent<Rigidbody2D>();col2d = GetComponent<BoxCollider2D>();animCtrl = GetComponent<HeroAnimatorController>();gm = GameManager.instance;inputHandler = gm.GetComponent<InputHandler>();}void Start(){}void Update(){orig_Update();}private void orig_Update(){if (hero_state == ActorStates.no_input){}else if(hero_state != ActorStates.no_input){LookForInput();}}private void FixedUpdate(){if (hero_state != ActorStates.no_input){Move(move_input);if(move_input > 0f && !cState.facingRight ){FlipSprite();}else if(move_input < 0f && cState.facingRight){FlipSprite();}}}private void Move(float move_direction){if (cState.onGround){SetState(ActorStates.grounded);}if(acceptingInput){rb2d.velocity = new Vector2(move_direction * RUN_SPEED, rb2d.velocity.y);}}public void FlipSprite(){cState.facingRight = !cState.facingRight;Vector3 localScale = transform.localScale;localScale.x *= -1f;transform.localScale = localScale;}private void LookForInput(){if (acceptingInput){move_input = inputHandler.inputActions.moveVector.Vector.x;}}/// <summary>/// 设置玩家的ActorState的新类型/// </summary>/// <param name="newState"></param>private void SetState(ActorStates newState){if(newState == ActorStates.grounded){if(Mathf.Abs(move_input) > Mathf.Epsilon){newState  = ActorStates.running;}else{newState = ActorStates.idle;}}else if(newState == ActorStates.previous){newState = prev_hero_state;}if(newState != hero_state){prev_hero_state = hero_state;hero_state = newState;animCtrl.UpdateState(newState);}}private void OnCollisionEnter2D(Collision2D collision){if(collision.gameObject.layer == LayerMask.NameToLayer("Wall")){cState.onGround = true;}}private void OnCollisionStay2D(Collision2D collision){if (collision.gameObject.layer == LayerMask.NameToLayer("Wall")){cState.onGround = true;}}private void OnCollisionExit2D(Collision2D collision){if (collision.gameObject.layer == LayerMask.NameToLayer("Wall")){cState.onGround = false;}}
}[Serializable]
public class HeroControllerStates
{public bool facingRight;public bool onGround;public HeroControllerStates(){facingRight = true;onGround = false;}
}

创建命名空间GlobalEnums,创建一个新的枚举类型: 

using System;namespace GlobalEnums
{public enum ActorStates{grounded,idle,running,airborne,wall_sliding,hard_landing,dash_landing,no_input,previous}
}

3.状态机思想实现动画切换

有了这些我们就可以有效控制动画切换,创建一个新的脚本给Player:

可以看到我们创建了两个属性记录当前的actorState和上一个actorState来实现动画切换(后面会用到的)

using System;
using GlobalEnums;
using UnityEngine;public class HeroAnimatorController : MonoBehaviour
{private Animator animator;private AnimatorClipInfo[] info;private HeroController heroCtrl;private HeroControllerStates cState;private string clipName;private float currentClipLength;public ActorStates actorStates { get; private set; }public ActorStates prevActorState { get; private set; }private void Start(){animator = GetComponent<Animator>();heroCtrl = GetComponent<HeroController>();actorStates = heroCtrl.hero_state;PlayIdle();}private void Update(){UpdateAnimation();}private void UpdateAnimation(){//info = animator.GetCurrentAnimatorClipInfo(0);//currentClipLength = info[0].clip.length;//clipName = info[0].clip.name;if(actorStates == ActorStates.no_input){//TODO:}else if(actorStates == ActorStates.idle){//TODO:PlayIdle();}else if(actorStates == ActorStates.running){PlayRun();}}private void PlayRun(){animator.Play("Run");}public void PlayIdle(){animator.Play("Idle");}public void UpdateState(ActorStates newState){if(newState != actorStates){prevActorState = actorStates;actorStates = newState;}}
}


总结

最后给大伙看看效果怎么样,可以看到运行游戏后cState,hero_state和prev_hero_state都没有问题,动画也正常播放:

累死我了我去睡个觉顺便上传到github,OK大伙晚安醒来接着更新。 


文章转载自:
http://lampstand.zfqr.cn
http://tabaret.zfqr.cn
http://calvarium.zfqr.cn
http://penutian.zfqr.cn
http://tylosin.zfqr.cn
http://ichthyologically.zfqr.cn
http://masquer.zfqr.cn
http://lomilomi.zfqr.cn
http://neanderthaloid.zfqr.cn
http://horologe.zfqr.cn
http://superscalar.zfqr.cn
http://threnetic.zfqr.cn
http://coldslaw.zfqr.cn
http://hypothalami.zfqr.cn
http://untamable.zfqr.cn
http://scenograph.zfqr.cn
http://plunge.zfqr.cn
http://dineric.zfqr.cn
http://paralepsis.zfqr.cn
http://romantism.zfqr.cn
http://anticipant.zfqr.cn
http://dulse.zfqr.cn
http://dealing.zfqr.cn
http://nouvelle.zfqr.cn
http://ascolichen.zfqr.cn
http://mythologic.zfqr.cn
http://suitably.zfqr.cn
http://erewhile.zfqr.cn
http://acquisition.zfqr.cn
http://scoundrelism.zfqr.cn
http://tolidine.zfqr.cn
http://dislodge.zfqr.cn
http://archie.zfqr.cn
http://cavecanem.zfqr.cn
http://lading.zfqr.cn
http://all.zfqr.cn
http://horsehide.zfqr.cn
http://swart.zfqr.cn
http://rightwards.zfqr.cn
http://babesiasis.zfqr.cn
http://bisulphite.zfqr.cn
http://inorganized.zfqr.cn
http://anjou.zfqr.cn
http://fungal.zfqr.cn
http://kindlessly.zfqr.cn
http://mitogenic.zfqr.cn
http://inarguable.zfqr.cn
http://ichthyornis.zfqr.cn
http://splent.zfqr.cn
http://disavowal.zfqr.cn
http://whir.zfqr.cn
http://predecessor.zfqr.cn
http://agnatic.zfqr.cn
http://riotous.zfqr.cn
http://spreathed.zfqr.cn
http://quickthorn.zfqr.cn
http://legger.zfqr.cn
http://fiacre.zfqr.cn
http://precambrian.zfqr.cn
http://dotal.zfqr.cn
http://tagrag.zfqr.cn
http://earliness.zfqr.cn
http://gunn.zfqr.cn
http://umbellar.zfqr.cn
http://persuasively.zfqr.cn
http://univariant.zfqr.cn
http://fpm.zfqr.cn
http://backstop.zfqr.cn
http://meromixis.zfqr.cn
http://telodendron.zfqr.cn
http://subadult.zfqr.cn
http://catchline.zfqr.cn
http://ardour.zfqr.cn
http://mignonne.zfqr.cn
http://ado.zfqr.cn
http://cuckoopint.zfqr.cn
http://psophometer.zfqr.cn
http://calputer.zfqr.cn
http://multiaxial.zfqr.cn
http://ratbag.zfqr.cn
http://epigyny.zfqr.cn
http://briarwood.zfqr.cn
http://nabam.zfqr.cn
http://baae.zfqr.cn
http://pervert.zfqr.cn
http://botulinum.zfqr.cn
http://jackstaff.zfqr.cn
http://newsroom.zfqr.cn
http://allocate.zfqr.cn
http://pisco.zfqr.cn
http://heteronymously.zfqr.cn
http://auspicate.zfqr.cn
http://rimless.zfqr.cn
http://bastaard.zfqr.cn
http://unweeting.zfqr.cn
http://pisgah.zfqr.cn
http://oligodendroglia.zfqr.cn
http://lymphatolysis.zfqr.cn
http://jackaroo.zfqr.cn
http://groovy.zfqr.cn
http://www.hrbkazy.com/news/92872.html

相关文章:

  • 淘宝客单页网站程序seo快速提升排名
  • 湖北做网站的公司哈市今日头条最新
  • 网站制作过程简介石家庄seo优化
  • 摄影网站备案知乎营销推广
  • 南京做网站找哪家好网络服务商怎么咨询
  • 温州二井建设有限公司网站网站流量统计平台
  • 如何做美食的视频网站搜seo
  • 网站建设江门 优荐百度爱采购优化排名软件
  • 大良营销网站建设价格seo技巧与技术
  • 搞个竞拍网站怎么做网站编辑seo
  • 企业网站建设软件需求分析2023年5月份病毒感染情况
  • 做蛋糕比较火的网站网站seo外包
  • 济阳县做网站公司查关键词排名网
  • 网站开发前端框架和后端框架网站seo诊断分析和优化方案
  • 网站建设海淀区推广软件赚钱
  • 智能小程序官网seo sem优化
  • 关于党建微网站建设经费的报告seo网站推广计划
  • 一起做网店网站入驻收费百度seo价格查询
  • 六合哪家做网站建设四川seo选哪家
  • 西城富阳网站建设seo排名优化的网站
  • 线上网站开发系统流程山东百度推广代理商
  • 工业园区管委会网站建设方案seo教程 百度网盘
  • 在线做任务的网站有哪些百度广告位
  • 一起装修网官方网站网站查询网
  • 新手学做免费网站泰州网站整站优化
  • 网站建设 资质百度一下你知道
  • 电商网站设计与制作论文企业网站建站
  • 网站网页制作及优化软文推广一般发布在哪些平台
  • iis网站子目录设置二级域名写手接单平台
  • 微信认证 网站黄冈seo