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

代理会计公司网站模版公司重名 做网站

代理会计公司网站模版,公司重名 做网站,服务好的赣州网站建设,企业搭建什么样的平台提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、第一个代表性场景 1.制作更多敌人2.制作更多可交互对象二、第二个代表性场景 1.制作更多敌人2.制作更多可交互对象三、第三个代表性场景 1.制作更多敌人2.制… 提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、第一个代表性场景 1.制作更多敌人2.制作更多可交互对象二、第二个代表性场景 1.制作更多敌人2.制作更多可交互对象三、第三个代表性场景 1.制作更多敌人2.制作更多可交互对象总结 前言 hello大家好久没见之所以隔了这么久才更新并不是因为我又放弃了这个项目而是接下来要制作的工作太忙碌了每次我都花了很长的时间解决完一个部分然后就没力气打开CSDN写文章就直接睡觉去了现在终于有时间整理下我这半个月都做了什么内容 废话少说接下来我将介绍我做的几个代表性场景主要是如标题说的制作更多地图更多敌人更多可交互对象 另外我的Github已经更新了想要查看最新的内容话请到我的Github主页下载工程吧 GitHub - ForestDango/Hollow-Knight-Demo: A new Hollow Knight Demo after 2 years! 一、第一个代表性场景 1.制作更多敌人 我们先把制作好创建吧还是老规矩先用tk2dTilemap绘制好基础的地图样貌并添加上Collider 然后堆叠素材添加上去这样一个场景就做好了 首先当然是从Town跳下井里的第一个场景Crossroads_01这里我们设置Town到Crossroads_01的TransitionPoint为top2 然后回到Crossroads中我们设置好全部的TransitionPoint这个top1别管 然后我们添加上敌人其实这里敌人没什么要讲的因为都是我们之前就做过的直接预制体拖上去就完事了 主要是要修复这个Zombie的bug我们之前做的Walker.cs脚本有问题现在让我们修复bug问题在EndStopping中我就说之前怎么会莫名其妙的转身 using System; using System.Collections; using System.Collections.Generic; using UnityEngine;public class Walker : MonoBehaviour {[Header(Structure)]//检测玩家的脚本一个不能少[SerializeField] private LineOfSightDetector lineOfSightDetector;[SerializeField] private AlertRange alertRange; //每一个敌人的四件公式化挂载rb2d,col2d,animator,audiosource,再加一个摄像头和hero位置private Rigidbody2D body;private Collider2D bodyCollider;private tk2dSpriteAnimator animator;private AudioSource audioSource;private Camera mainCamera;private HeroController hero;private const float CameraDistanceForActivation 60f;private const float WaitHeroXThreshold 1f; //距离玩家X方向上的极限距离值[Header(Configuration)][SerializeField] private bool ambush; //是否埋伏[SerializeField] private string idleClip; //idle的动画片段名字[SerializeField] private string turnClip; //turn的动画片段名字[SerializeField] private string walkClip; //walk的动画片段名字[SerializeField] private float edgeXAdjuster; //检测墙沿x上的增加值[SerializeField] private bool preventScaleChange; //是否防止x轴的localscale发生变化[SerializeField] private bool preventTurn; //是否阻止转向[SerializeField] private float pauseTimeMin; //停止不动的时间[SerializeField] private float pauseTimeMax;[SerializeField] private float pauseWaitMin; //走路的时间[SerializeField] private float pauseWaitMax;[SerializeField] private bool pauses; //是否需要静止状态[SerializeField] private float rightScale; //开始时的x轴方向[SerializeField] public bool startInactive; //开始时不活跃[SerializeField] private int turnAfterIdlePercentage; //Idle状态过后进入转身Turn状态的概率[SerializeField] private float turnPause; //设置转身的冷却时间[SerializeField] private bool waitForHeroX; //是否等待玩家X方向到位[SerializeField] private float waitHeroX; //等待玩家X方向距离[SerializeField] public float walkSpeedL; //向左走路的速度[SerializeField] public float walkSpeedR;//向右走路的速度[SerializeField] public bool ignoreHoles; //是否忽略洞[SerializeField] private bool preventTurningToFaceHero; //防止转向玩家的位置[SerializeField] private Walker.States state;[SerializeField] private Walker.StopReasons stopReason;private bool didFulfilCameraDistanceCondition; //暂时没有用到private bool didFulfilHeroXCondition; //暂时没有用到private int currentFacing;//Debug的时候可以在前面加个[SerializeField]private int turningFacing;//三个计时器且顾名思义private float walkTimeRemaining;private float pauseTimeRemaining;private float turnCooldownRemaining;protected void Awake(){body GetComponentRigidbody2D();bodyCollider GetComponentBoxCollider2D();animator GetComponenttk2dSpriteAnimator();audioSource GetComponentAudioSource();}protected void Start(){mainCamera Camera.main;hero HeroController.instance;if(currentFacing 0){currentFacing ((transform.localScale.x * rightScale 0f) ? 1 : -1); //左边是-1右边是1}if(state States.NotReady){turnCooldownRemaining -Mathf.Epsilon;BeginWaitingForConditions();}}/// summary/// 我们创建另一个状态机分为四种状态每一种都有Update和Stop的方法。/// /summaryprotected void Update(){turnCooldownRemaining - Time.deltaTime;switch (state){case States.WaitingForConditions:UpdateWaitingForConditions();break;case States.Stopped:UpdateStopping();break;case States.Walking:UpdateWalking();break;case States.Turning:UpdateTurning();break;default:break;}}/// summary/// 从Waiting状态进入开始移动状态(不一定是Walk也可能是Turn)/// /summarypublic void StartMoving(){if(state States.Stopped || state States.WaitingForConditions){startInactive false;int facing;if(currentFacing 0){facing UnityEngine.Random.Range(0, 2) 0 ? -1 : 1;}else{facing currentFacing;}BeginWalkingOrTurning(facing);}Update();}/// summary/// 在需要时取消转向/// /summarypublic void CancelTurn(){if(state States.Turning){BeginWalking(currentFacing);}}public void Go(int facing){turnCooldownRemaining -Time.deltaTime;if(state States.Stopped || state States.Walking){BeginWalkingOrTurning(facing);}else if(state States.Turning currentFacing facing){CancelTurn();}Update();}public void ReceiveGoMessage(int facing) //TODO:{if(state ! States.Stopped || stopReason ! StopReasons.Controlled){Go(facing);}}/// summary/// 被脚本StopWalker.cs调用更改reason为controlled/// /summary/// param namereason/parampublic void Stop(StopReasons reason){BeginStopped(reason);}/// summary/// 更改turningFacing和currentFacing属于Turn状态的行为/// /summary/// param namefacing/parampublic void ChangeFacing(int facing){if(state States.Turning){turningFacing facing;currentFacing -facing;return;}currentFacing facing;}/// summary/// 开始进入等待状态/// /summaryprivate void BeginWaitingForConditions(){state States.WaitingForConditions;didFulfilCameraDistanceCondition false;didFulfilHeroXCondition false;UpdateWaitingForConditions();}/// summary/// 在Update以及BeginWaitingForConditions两大函数中调用更新等待状态下的行为/// /summaryprivate void UpdateWaitingForConditions(){if (!didFulfilCameraDistanceCondition (mainCamera.transform.position - transform.position).sqrMagnitude CameraDistanceForActivation * CameraDistanceForActivation){didFulfilCameraDistanceCondition true;}if(didFulfilCameraDistanceCondition !didFulfilHeroXCondition hero ! null Mathf.Abs(hero.transform.position.x - waitHeroX) WaitHeroXThreshold) //TODO:{didFulfilHeroXCondition true;}if(didFulfilCameraDistanceCondition (!waitForHeroX || didFulfilHeroXCondition) !startInactive !ambush){BeginStopped(StopReasons.Bored);StartMoving();}}/// summary/// 开始进入停止状态/// /summary/// param namereason/paramprivate void BeginStopped(StopReasons reason){state States.Stopped;stopReason reason;if (audioSource){audioSource.Stop();}if(reason StopReasons.Bored){tk2dSpriteAnimationClip clipByName animator.GetClipByName(idleClip);if(clipByName ! null){animator.Play(clipByName);}body.velocity Vector2.Scale(body.velocity, new Vector2(0f, 1f)); //相当于把x方向上的速度设置为0if (pauses){pauseTimeRemaining UnityEngine.Random.Range(pauseTimeMin, pauseTimeMax);return;}EndStopping();}}/// summary/// 在Update中被调用执行停止Stop状态的行为/// /summaryprivate void UpdateStopping(){if(stopReason StopReasons.Bored){pauseTimeRemaining - Time.deltaTime;if(pauseTimeRemaining 0f){EndStopping();}}}/// summary/// 终止停止状态/// /summaryprivate void EndStopping(){if(currentFacing 0){BeginWalkingOrTurning(UnityEngine.Random.Range(0, 2) 0 ? 1 : -1);return;}if(UnityEngine.Random.Range(0,100) turnAfterIdlePercentage){BeginTurning(-currentFacing);return;}BeginWalking(currentFacing); //这里应该是开始行走Walk而不是开始转向Turn}/// summary/// 要不走路要不转身/// /summary/// param namefacing/paramprivate void BeginWalkingOrTurning(int facing){if(currentFacing facing){BeginWalking(facing);return;}BeginTurning(facing);}/// summary/// 开始进入Walking状态/// /summary/// param namefacing/paramprivate void BeginWalking(int facing){state States.Walking;animator.Play(walkClip);if (!preventScaleChange){transform.SetScaleX(facing * rightScale);}walkTimeRemaining UnityEngine.Random.Range(pauseWaitMin, pauseWaitMax);if (audioSource){audioSource.Play();}body.velocity new Vector2((facing 0) ? walkSpeedR : walkSpeedL,body.velocity.y);}/// summary/// 在Update中被调用动态执行Walking状态根据情况决定是否要进入Turning状态或者Stopped状态/// /summaryprivate void UpdateWalking(){if(turnCooldownRemaining 0f){Sweep sweep new Sweep(bodyCollider, 1 - currentFacing, Sweep.DefaultRayCount,Sweep.DefaultSkinThickness);if (sweep.Check(transform.position, bodyCollider.bounds.extents.x 0.5f, LayerMask.GetMask(Terrain))){BeginTurning(-currentFacing);return;}if (!preventTurningToFaceHero (hero ! null hero.transform.GetPositionX() transform.GetPositionX() ! currentFacing 0) lineOfSightDetector ! null lineOfSightDetector.CanSeeHero alertRange ! null alertRange.IsHeroInRange){BeginTurning(-currentFacing);return;}if (!ignoreHoles){Sweep sweep2 new Sweep(bodyCollider, DirectionUtils.Down, Sweep.DefaultRayCount, 0.1f);if (!sweep2.Check((Vector2)transform.position new Vector2((bodyCollider.bounds.extents.x 0.5f edgeXAdjuster) * currentFacing, 0f), 0.25f, LayerMask.GetMask(Terrain))){BeginTurning(-currentFacing);return;}}}if (pauses){walkTimeRemaining - Time.deltaTime;if(walkTimeRemaining 0f){BeginStopped(StopReasons.Bored);return;}}body.velocity new Vector2((currentFacing 0) ? walkSpeedR : walkSpeedL, body.velocity.y);}private void BeginTurning(int facing){state States.Turning;turningFacing facing;if (preventTurn){EndTurning();return;}turnCooldownRemaining turnPause;body.velocity Vector2.Scale(body.velocity, new Vector2(0f, 1f));animator.Play(turnClip);FSMUtility.SendEventToGameObject(gameObject, (facing 0) ? TURN RIGHT : TURN LEFT, false);}/// summary/// 在Update中被调用执行Turning转身状态。/// /summaryprivate void UpdateTurning(){body.velocity Vector2.Scale(body.velocity, new Vector2(0f, 1f));if (!animator.Playing){EndTurning();}}/// summary/// 被UpdateTurning()调用当动画播放完成后切换到Walking状态。/// 被BeginTurning()调用当preventTurn为true时就不再向下执行了。/// /summaryprivate void EndTurning(){currentFacing turningFacing;BeginWalking(currentFacing);}/// summary/// 就清空turnCooldownRemaining/// /summarypublic void ClearTurnCoolDown(){turnCooldownRemaining -Mathf.Epsilon;}public enum States{NotReady,WaitingForConditions,Stopped,Walking,Turning}public enum StopReasons{Bored,Controlled}}然后我们在面板中重新设置好参数 2.制作更多可交互对象 这个场景里可交互的貌似只有这个杆我们添加好它的顶部和底部并设置好位置添加上layer然后新建脚本BreakablePole.cs using System.Collections; using System.Collections.Generic; using UnityEngine;public class BreakablePole : MonoBehaviour,IHitResponder {[SerializeField] private SpriteRenderer spriteRenderer;[SerializeField] private Sprite brokenSprite;[SerializeField] private float inertBackgroundThreshold;[SerializeField] private float inertForegroundThreshold;[SerializeField] private AudioSource audioSourcePrefab;[SerializeField] private RandomAudioClipTable hitClip;[SerializeField] private GameObject slashImpactPrefab;[SerializeField] private Rigidbody2D top;protected void Reset(){inertBackgroundThreshold -1f;inertForegroundThreshold -1f;}protected void Start(){float z transform.position.z;if(z inertBackgroundThreshold || z inertForegroundThreshold){enabled false;return;}}public void Hit(HitInstance damageInstance){int cardinalDirection DirectionUtils.GetCardinalDirection(damageInstance.Direction);if (cardinalDirection ! 2 cardinalDirection ! 0){return;}spriteRenderer.color new Color(spriteRenderer.color.r, spriteRenderer.color.g, spriteRenderer.color.b,0f);Transform transform Instantiate(slashImpactPrefab).transform;transform.eulerAngles new Vector3(0f, 0f, Random.Range(340f, 380f));Vector3 localScale transform.localScale;localScale.x ((cardinalDirection 2) ? -1f : 1f);localScale.y 1f;hitClip.SpawnAndPlayOneShot(audioSourcePrefab, base.transform.position);if (top ! null){top.gameObject.SetActive(true);float num (cardinalDirection 2) ? Random.Range(120, 140) : Random.Range(40, 60);top.transform.localScale new Vector3(localScale.x, localScale.y, top.transform.localScale.z);top.velocity new Vector2(Mathf.Cos(num * 0.017453292f), Mathf.Sin(num * 0.017453292f)) * 5f;top.transform.Rotate(new Vector3(0f, 0f, num));base.enabled false;}} }然后设置好参数 二、第二个代表性场景 1.制作更多敌人 然后就是大家喜闻乐见的长场景Crossroads_07,这个场景相当于一个区域的中转站既可以向左走去虫爷爷和苍绿之境或者打boss躁郁的毛里克亦可以向右走去打假骑士和苍蝇之母鹿角站矿井等等不过这些都是后话了我们先来把地图做好添加上对应的TranstionPoint: 其实做到这里我才意识到要把这四个 TranstionPoint做成预制体。 然后敌人自然是到处飞的苍蝇fly了 2.制作可交互对象 为了让场景看起来生动我们可以添加背景板里飞走的蚊子buzzer用particlesystem来实现 第二个 然后就是踩一下会发出声音的平台 我们来给它们新建一个脚本LiftPlatform.cs实现了个功能当角色踩上去时上下移动一下播放粒子系统和声音 using System.Collections; using System.Collections.Generic; using UnityEngine;public class LiftPlatform : MonoBehaviour {public GameObject part1;public GameObject part2;public ParticleSystem dustParticle;public AudioSource source;private float part1_start_y;private float part2_start_y;private int state;private float timer;private void Start(){part1_start_y part1.transform.position.y;part2_start_y part2.transform.position.y;}private void Update(){if(state 1){if (timer 0.125f){part1.transform.position new Vector3(part1.transform.position.x, part1_start_y - timer * 0.75f, part1.transform.position.z);part2.transform.position new Vector3(part2.transform.position.x, part2_start_y - timer * 0.75f, part2.transform.position.z);timer Time.deltaTime;}else{part1.transform.position new Vector3(part1.transform.position.x, part1_start_y - 0.09f, part1.transform.position.z);part2.transform.position new Vector3(part2.transform.position.x, part2_start_y - 0.09f, part2.transform.position.z);state 2;timer 0.12f;}}if(state 2){if (timer 0f){part1.transform.position new Vector3(part1.transform.position.x, part1_start_y - timer * 0.75f, part1.transform.position.z);part2.transform.position new Vector3(part2.transform.position.x, part2_start_y - timer * 0.75f, part2.transform.position.z);timer - Time.deltaTime;return;}part1.transform.position new Vector3(part1.transform.position.x, part1_start_y, part1.transform.position.z);part2.transform.position new Vector3(part2.transform.position.x, part2_start_y, part2.transform.position.z);state 0;}}private void OnCollisionEnter2D(Collision2D collision){if(state 0 collision.collider.gameObject.layer ! LayerMask.NameToLayer(Item) collision.gameObject.layer ! LayerMask.NameToLayer(Particle) collision.gameObject.layer ! LayerMask.NameToLayer(Enemies) collision.GetSafeContact().Normal.y 0.1f){source.pitch Random.Range(0.85f, 1.15f);source.Play();dustParticle.Play();state 0;timer 0f;}}}三、第三个代表性场景 1.制作更多的敌人 其实这个场景我就想将新制作的敌人的没错就是这个拿骨钉盾牌的僵尸虫 我们回到tk2dSprite和tk2danimator给它创建好 你只需要记住A是anticipate攻击准备阶段的动画L是Lunge突刺动画S是攻击时的动画CD是冷却时候的动画 然后剩下的dddd。这个Bump就是反弹骨钉攻击的动画。OK说的差不多了然后Unsheild和sheild动画就是反过来的。 然后就是添加相应的脚本到场景中 s上面的脚本我在之前的文章都讲过了除了这个EnemyDeathEffects using System; using HutongGames.PlayMaker; using UnityEngine; using UnityEngine.Audio;public class EnemyDeathEffects : MonoBehaviour {[SerializeField] private GameObject corpsePrefab;[SerializeField] private bool corpseFacesRight;[SerializeField] private float corpseFlingSpeed;[SerializeField] public Vector3 corpseSpawnPoint;[SerializeField] private string deathBroadcastEvent;[SerializeField] private Vector3 effectOrigin;[SerializeField] private bool lowCorpseArc;[SerializeField] private EnemyDeathTypes enemyDeathType;[SerializeField] protected AudioSource audioPlayerPrefab;[SerializeField] protected AudioEvent enemyDeathSwordAudio;[SerializeField] protected AudioEvent enemyDamageAudio;[SerializeField] protected AudioClip enemyDeathSwordClip;[SerializeField] protected AudioClip enemyDamageClip;[SerializeField] private AudioMixerSnapshot audioSnapshotOnDeath;[SerializeField] protected GameObject deathWaveInfectedPrefab;[SerializeField] protected GameObject deathWaveInfectedSmallPrefab;[SerializeField] private bool recycle;[SerializeField] private bool rotateCorpse; //尸体需要旋转吗[SerializeField] protected GameObject dustPuffMedPrefab;[SerializeField] protected GameObject deathPuffLargePrefab;protected GameObject corpse;private bool didFire;[HideInInspector]public bool doKillFreeze true;protected void Start(){PreInstantiate();}public void PreInstantiate(){if(!corpse corpsePrefab){corpse Instantiate(corpsePrefab, transform.position corpseSpawnPoint, Quaternion.identity, transform);tk2dSprite[] componentInChildrens corpse.GetComponentsInChildrentk2dSprite(true);for (int i 0; i componentInChildrens.Length; i){componentInChildrens[i].ForceBuild();}corpse.SetActive(false);}}public void RecieveDeathEvent(float? attackDirection, bool resetDeathEvent false, bool spellBurn false, bool isWatery false){if (didFire)return;didFire true;if(corpse ! null){EmitCorpse(attackDirection, isWatery, spellBurn);}if (!isWatery){EmitEffects();}if (doKillFreeze){GameManager.instance.FreezeMoment(1);}if (enemyDeathType EnemyDeathTypes.Infected || enemyDeathType EnemyDeathTypes.LargeInfected || enemyDeathType EnemyDeathTypes.SmallInfected || enemyDeathType EnemyDeathTypes.Uninfected ){EmitEssence();}if (audioSnapshotOnDeath ! null){audioSnapshotOnDeath.TransitionTo(2f);}if (!string.IsNullOrEmpty(deathBroadcastEvent)){Debug.LogWarningFormat(this, Death broadcast event {0} not implemented!, new object[]{deathBroadcastEvent});}if (resetDeathEvent){FSMUtility.SendEventToGameObject(gameObject, CENTIPEDE DEATH, false);didFire false;return;}if (recycle){PlayMakerFSM playMakerFSM FSMUtility.LocateFSM(gameObject, health_manager_enemy);if(playMakerFSM ! null){playMakerFSM.FsmVariables.GetFsmBool(Activated).Value false;}HealthManager component2 GetComponentHealthManager();if(component2 ! null){component2.SetIsDead(false);}didFire false;//TODO:return;}Destroy(gameObject);}private void EmitCorpse(float? attackDirection, bool isWatery, bool spellBurn){if (corpse null)return;corpse.transform.SetParent(null);corpse.transform.SetPositionZ(UnityEngine.Random.Range(-0.08f, -0.09f));corpse.SetActive(true);PlayMakerFSM playMakerFSM FSMUtility.LocateFSM(corpse, corpse);if(playMakerFSM ! null){FsmBool fsmBool playMakerFSM.FsmVariables.GetFsmBool(spellBurn);if(fsmBool! null){fsmBool.Value false;}}Corpse component corpse.GetComponentCorpse();if (component){component.Setup(isWatery, spellBurn);}if (isWatery){return;}corpse.transform.SetRotation2D(rotateCorpse ? transform.GetRotation2D():0f);if(Mathf.Abs(transform.eulerAngles.z) 45f){Collider2D component2 GetComponentCollider2D();Collider2D component3 corpse.GetComponentCollider2D();if(!rotateCorpse component2 component3){Vector3 b component2.bounds.center - component3.bounds.center;b.z 0f;corpse.transform.position b;}}float d 1f;if(attackDirection null){d 0f;}int cardinalDirection DirectionUtils.GetCardinalDirection(attackDirection.GetValueOrDefault());Rigidbody2D component4 corpse.GetComponentRigidbody2D();if(component4 ! null !component4.isKinematic){float num corpseFlingSpeed;float num2;switch (cardinalDirection){case 0:num2 lowCorpseArc ? 10f : 60f;corpse.transform.SetScaleX(corpse.transform.localScale.x * (corpseFacesRight ? -1f : 1f) * Mathf.Sign(transform.localScale.x));break;case 1:num2 UnityEngine.Random.Range(75f, 105f);num * 1.3f;break;case 2:num2 lowCorpseArc ? 170f : 120f;corpse.transform.SetScaleX(corpse.transform.localScale.x * (corpseFacesRight ? 1f : -1f) * Mathf.Sign(transform.localScale.x));break;case 3:num2 270f;break;default:num2 90f;break;}component4.velocity new Vector2(Mathf.Cos(num2 * 0.017453292f), Mathf.Sin(num2 * 0.017453292f)) * num * d;}}private void EmitEffects(){EnemyDeathTypes enemyDeathTypes enemyDeathType;if(enemyDeathTypes EnemyDeathTypes.Infected){EmitInfectedEffects();return;}if (enemyDeathTypes EnemyDeathTypes.SmallInfected){EmitSmallInfectedEffects();return;}if (enemyDeathTypes ! EnemyDeathTypes.LargeInfected){Debug.LogWarningFormat(this, Enemy death type {0} not implemented!, new object[]{enemyDeathType});return;}EmitLargeInfectedEffects();}private void EmitLargeInfectedEffects(){AudioEvent audioEvent default(AudioEvent);audioEvent.Clip enemyDeathSwordClip;audioEvent.PitchMin 0.75f;audioEvent.PitchMax 0.75f;audioEvent.Volume 1f;audioEvent.SpawnAndPlayOneShot(audioPlayerPrefab, transform.position);audioEvent default(AudioEvent);audioEvent.Clip enemyDamageClip;audioEvent.PitchMin 0.75f;audioEvent.PitchMax 0.75f;audioEvent.Volume 1f;audioEvent.SpawnAndPlayOneShot(audioPlayerPrefab, transform.position);if(corpse ! null){SpriteFlash component corpse.GetComponentSpriteFlash();if(component ! null){component.flashInfected();}}if (!(deathPuffLargePrefab null)){Instantiate(deathPuffLargePrefab, transform.position effectOrigin, Quaternion.identity);}ShakeCameraIfVisible(AverageShake);if (!(deathWaveInfectedPrefab null)){GameObject gameObject Instantiate(deathWaveInfectedPrefab, transform.position effectOrigin, Quaternion.identity);gameObject.transform.SetScaleX(2f);gameObject.transform.SetScaleY(2f);}GlobalPrefabDefaults.Instance.SpawnBlood(transform.position effectOrigin, 75, 80, 20f, 25f, 0f, 360f, null);}private void EmitSmallInfectedEffects(){AudioEvent audioEvent default(AudioEvent);audioEvent.Clip enemyDeathSwordClip;audioEvent.PitchMin 1.2f;audioEvent.PitchMax 1.4f;audioEvent.Volume 1f;audioEvent.SpawnAndPlayOneShot(audioPlayerPrefab, transform.position);audioEvent default(AudioEvent);audioEvent.Clip enemyDamageClip;audioEvent.PitchMin 1.2f;audioEvent.PitchMax 1.4f;audioEvent.Volume 1f;audioEvent.SpawnAndPlayOneShot(audioPlayerPrefab, transform.position);if (deathWaveInfectedSmallPrefab ! null){GameObject gameObject Instantiate(deathWaveInfectedSmallPrefab, transform.position effectOrigin,Quaternion.identity);Vector3 localScale gameObject.transform.localScale;localScale.x 0.5f;localScale.y 0.5f;gameObject.transform.localScale localScale;}GlobalPrefabDefaults.Instance.SpawnBlood(transform.position effectOrigin, 8, 10, 15f, 20f, 0, 360, null);}private void EmitInfectedEffects(){EmitSound();if(corpse ! null){SpriteFlash component corpse.GetComponentSpriteFlash();if(component ! null){component.flashInfected();}}GameObject gameObject Instantiate(deathWaveInfectedPrefab, transform.position effectOrigin, Quaternion.identity);gameObject.transform.SetScaleX(1.25f);gameObject.transform.SetPositionY(1.25f);GlobalPrefabDefaults.Instance.SpawnBlood(transform.position effectOrigin, 8, 10, 15f, 20f, 0, 360, null);Instantiate(dustPuffMedPrefab, transform.position effectOrigin, Quaternion.identity);ShakeCameraIfVisible(EnemyKillShake);}private void EmitSound(){enemyDeathSwordAudio.SpawnAndPlayOneShot(audioPlayerPrefab, transform.position);enemyDamageAudio.SpawnAndPlayOneShot(audioPlayerPrefab, transform.position);}private void EmitEssence(){//TODO:和梦之钉有关的PlayerData playerData GameManager.instance.playerData;if (!playerData.hasDreamNail){return; }}protected void ShakeCameraIfVisible(string eventName){Renderer renderer GetComponentRenderer();if (renderer null){renderer GetComponentInChildrenRenderer();}if (renderer ! null renderer.isVisible){GameCameras.instance.cameraShakeFSM.SendEvent(eventName);}}}在面板中添加好参数后我们就到HealthManager中 public class HealthManager : MonoBehaviour, IHitResponder {private EnemyDeathEffects enemyDeathEffects;protected void Awake(){enemyDeathEffects GetComponentEnemyDeathEffects();}public void Die(float? attackDirection, AttackTypes attackType, bool ignoreEvasion){if (isDead){ return;}if (sprite){sprite.color Color.white;}FSMUtility.SendEventToGameObject(gameObject, ZERO HP, false);if (hasSpecialDeath){NonFatalHit(ignoreEvasion);return;}isDead true;if(damageHero ! null){damageHero.damageDealt 0;}if(battleScene ! null !notifiedBattleScene){PlayMakerFSM playMakerFSM FSMUtility.LocateFSM(battleScene, Battle Control);if(playMakerFSM ! null){FsmInt fsmInt playMakerFSM.FsmVariables.GetFsmInt(Battle Enemies);if(fsmInt ! null){fsmInt.Value--;notifiedBattleScene true;}}}if (enemyDeathEffects ! null){if (attackType AttackTypes.Generic){enemyDeathEffects.doKillFreeze false;}enemyDeathEffects.RecieveDeathEvent(attackDirection, deathReset, attackType AttackTypes.Spell, false);}SendDeathEvent();Destroy(gameObject); //TODO:} } 还有我们将蚊子那期介绍的老朋友攻击距离检测警戒距离检测         还有类似于玩家的slash的polygon collider2d别忘了给它们添加上damagehero脚本 还有一个就是当僵尸虫进入冲刺状态上播放的粒子系统dust 接下来就到了我们老朋友playmakerFSM登场了老规矩我先贴出来变量和事件然后逐个讲状态 第一个状态当然是初始化了 每一帧都检测玩家是否到可视范围和攻击范围了 判断玩家位置  我们先做好playmakerFSM自定义脚本 using HutongGames.PlayMaker; using UnityEngine;[ActionCategory(Hollow Knight)] public class SetInvincible : FsmStateAction {[UIHint(UIHint.Variable)]public FsmOwnerDefault target;public FsmBool Invincible;public FsmInt InvincibleFromDirection;public override void Reset(){target new FsmOwnerDefault();Invincible null;InvincibleFromDirection null;}public override void OnEnter(){GameObject safe target.GetSafe(this);if (safe ! null){HealthManager component safe.GetComponentHealthManager();if (component ! null){if (!Invincible.IsNone){component.IsInvincible Invincible.Value;}if (!InvincibleFromDirection.IsNone){component.InvincibleFromDirection InvincibleFromDirection.Value;}}}Finish();}}using HutongGames.PlayMaker; using UnityEngine;[ActionCategory(Hollow Knight)] public class SetWalkerFacing : WalkerAction {public FsmBool walkRight;public FsmBool randomStartDir;public override void Reset(){base.Reset();walkRight new FsmBool{UseVariable true};randomStartDir new FsmBool();}/// summary/// 调用Walker.cs中的ChangeFacing函数来改变朝向/// /summary/// param namewalker/paramprotected override void Apply(Walker walker){if (randomStartDir.Value){walker.ChangeFacing((Random.Range(0, 2) 0) ? -1 : 1);return;}if (!walkRight.IsNone){walker.ChangeFacing(walkRight.Value ? 1 : -1);}}}剩下三个都差不多你只需要设置好tk2d动画Lung1 Speed和Lung2 Speed的正负判断不同方向的事件以及sheild格挡的方向 触发BLOCKED HIT的事件该执行的状态 这个BLOCKED HIT的事件在HealthManager.cs中会触发的让我们回到HealthManager.cs脚本中 public void Invincible(HitInstance hitInstance){int cardinalDirection DirectionUtils.GetCardinalDirection(hitInstance.GetActualDirection(transform));directionOfLastAttack cardinalDirection;FSMUtility.SendEventToGameObject(gameObject, BLOCKED HIT, false);FSMUtility.SendEventToGameObject(hitInstance.Source, HIT LANDED, false);if (!(GetComponentDontClinkGates() ! null)){FSMUtility.SendEventToGameObject(gameObject, HIT, false);if(hitInstance.AttackType AttackTypes.Nail){if(cardinalDirection 0){HeroController.instance.RecoilLeft();}else if(cardinalDirection 2){HeroController.instance.RecoilRight();}}Vector2 v;Vector3 eulerAngles;if (boxCollider ! null){switch (cardinalDirection){case 0:v new Vector2(transform.GetPositionX() boxCollider.offset.x - boxCollider.size.x * 0.5f, hitInstance.Source.transform.GetPositionY());eulerAngles new Vector3(0f, 0f, 0f);break;case 1:v new Vector2(hitInstance.Source.transform.GetPositionX(), Mathf.Max(hitInstance.Source.transform.GetPositionY(), transform.GetPositionY() boxCollider.offset.y - boxCollider.size.y * 0.5f));eulerAngles new Vector3(0f, 0f, 90f);break;case 2:v new Vector2(transform.GetPositionX() boxCollider.offset.x boxCollider.size.x * 0.5f, hitInstance.Source.transform.GetPositionY());eulerAngles new Vector3(0f, 0f, 180f);break;case 3:v new Vector2(hitInstance.Source.transform.GetPositionX(), Mathf.Min(hitInstance.Source.transform.GetPositionY(), transform.GetPositionY() boxCollider.offset.y boxCollider.size.y * 0.5f));eulerAngles new Vector3(0f, 0f, 270f);break;default:break;}}else{v transform.position;eulerAngles new Vector3(0f, 0f, 0f);}}evasionByHitRemaining 0.15f;} 那么这个方法在哪里被调用呢当然是我们的HIT方法了如果你还有印象这个就是继承接口IHitResponder要实现的方法 public void Hit(HitInstance hitInstance){if (isDead){return;}if(evasionByHitRemaining 0f) { return;}if(hitInstance.DamageDealt 0f){return;}FSMUtility.SendEventToGameObject(hitInstance.Source, DEALT DAMAGE, false);int cardinalDirection DirectionUtils.GetCardinalDirection(hitInstance.GetActualDirection(transform));if (IsBlockingByDirection(cardinalDirection, hitInstance.AttackType)){Invincible(hitInstance);return;}TakeDamage(hitInstance);} 判断当前攻击方向是否格挡 [Header(Invincible)][SerializeField] private bool invincible;[SerializeField] private int invincibleFromDirection;public bool IsBlockingByDirection(int cardinalDirection,AttackTypes attackType){ //法术攻击无法格挡if(attackType AttackTypes.Spell gameObject.CompareTag(Spell Vulnerable)){return false;} //不是无敌无法格挡if (!invincible){return false;} //没有确切的方向无法格挡if(invincibleFromDirection 0){return true;}switch (cardinalDirection){case 0:{int num invincibleFromDirection;if (num 5){if (num ! 1 num ! 5){return false;}}else if (num ! 8 num ! 10){return false;}return true;} case 1:{int num invincibleFromDirection;return num 2 || num - 5 4;}case 2:{int num invincibleFromDirection;if (num 6){if (num ! 3 num ! 6){return false;}}else if (num ! 9 num ! 11){return false;}return true;}case 3:{int num invincibleFromDirection;return num 4 || num - 7 4;}default:return false;}} 格挡以后自然是要对玩家发起攻击了 首先进入准备阶段 向前冲刺阶段 攻击阶段在这里就要打开我们创建的slash的碰撞箱了同时将僵尸虫的速度位置为0  冷却阶段关闭碰撞箱 然后突然虚晃一枪接着对玩家发动二段攻击没有准备阶段直接进入冲刺攻击阶段 二阶段的冷却 三阶段的再次冲刺攻击阶段  三阶段的攻击阶段 三阶段的冷却阶段应该不叫冷却而是叫停止攻击阶段 重置walker状态  除了自动攻击我们还有主动攻击阶段内容我就不赘述了直接上图 还有就是玩家离开可视范围和攻击距离发送LEFT RANGE事件把举起的盾牌放下来 总结 我们来看看上述讲到的三个场景的效果上面的UI先别管我之后会完成的 虫子的转身没问题的 平台没问题的  然后僵尸盾牌虫直接攻击Attack 1 它在反击后的攻击是水平方向的因此我可以下劈它 由于我没做格挡时的动画虽然不明显但是还是能看到敌人并没有因为我的攻击而受到伤害。。 三段攻击也有但我忘了截屏了就先这样吧下一期我们来制作更多的敌人和更多的场景
http://www.tj-hxxt.cn/news/231074.html

相关文章:

  • 做网站好平台化新浪云平台创建wordpress
  • 申请建设单位门户网站的请示电子商务的特点
  • 上海优化网站关键词wordpress替代2017
  • 凡科做的网站户外网站建设
  • 做的最好的视频网站在安阳想建个网站怎么做
  • 如何做企业网站小程序育才网站建设
  • 中国安能建设集团有网站网站集约化建设 通知
  • 阿里云9元做网站男女这样做那个网站
  • 网站建设概政务公开 网站建设滞后
  • 苏州网站制作的公司wordpress 主题小工具
  • 郑州做企业网站互动平台论坛
  • 中国铁建商城电子商务平台网站优化推广的方法
  • 58做网站联系电话医院网站设计与实现
  • 徐州网站开发设计公司电话微信公众号配置 网站建设
  • 猎场第几集做的网站推广网站被降权会发生什么
  • 免费网站模禁止wordpress自动更新
  • 网站建设模板系统查建设工程规划许可证网站
  • 网站年报公示怎么做那个网站有题做
  • wordpress acg站江苏分销网站建设
  • 园洲做网站公司网站开发的话术
  • 一个网站里有两个网页怎么做html在wordpress中的作用
  • 企业网站的建立与维护论文搭建网站的英语
  • 西安电子商务网站开发高新公司网站建设电话
  • 网站建实例专门做拼团的网站
  • 哪个网站可以做公众号封面报告网站开发环境
  • 黑龙江建设银行网站房屋租赁网站建设如何给客户定位
  • 建设农产品网络营销网站枣阳网站建设_枣阳山水数码
  • php企业门户网站佛山顺德容桂网站制作
  • 网站建设项目分析报告西安网站建设云速网络
  • 流行的网站开发语言四川省凉亭建设工程有限公司网站