Forum begins after the advertisement:
[Part 6] crawler not flipping
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 6] crawler not flipping
- This topic has 8 replies, 2 voices, and was last updated 5 months, 1 week ago by Ethan.
-
AuthorPosts
-
April 30, 2024 at 8:33 pm #14437EthanParticipant::
ive posted the code below but the crawler will not flip rn
using System.Collections;
using System.Collections.Generic;
using System.Transactions;
using UnityEngine;public class Crawler : Enemy
{
[SerializeField] private float flipWaitTime;
[SerializeField] private float ledgeCheckX;
[SerializeField] private float ledgeCheckY;
[SerializeField] private LayerMask whatIsGround;
float timer;
// Start is called before the first frame update
protected override void Start()
{
base.Start();
rb.gravityScale = 12.0f;
}protected override void Update()
{
base.Update();
if(!isRecoiling)
{
transform.position=Vector2.MoveTowards
(transform.position,new Vector2(PlayerController.Instance.transform.position.x, transform.position.y),speed *Time.deltaTime);
}
}
protected override void UpdateEnemyStates()
{
switch(currentEnemyState)
{
case EnemyStates.Crawler_Idle:
Vector3 _ledgeCheckStart = transform.localScale.x > 0 ? new Vector3(ledgeCheckX, 0) : new Vector3(-ledgeCheckX, 0);
Vector2 _wallCheckDir = transform.localScale.x > 0 ? transform.right : -transform.right;if (!Physics2D.Raycast(transform.position + _ledgeCheckStart, Vector2.down, ledgeCheckY, whatIsGround)
|| Physics2D.Raycast(transform.position, _wallCheckDir, ledgeCheckX, whatIsGround))
{
ChangeState(EnemyStates.Crawler_Flip);
}if (transform.localScale.x>0)
{
rb.velocity= new Vector2(speed, rb.velocity.y);
}
else
{
rb.velocity= new Vector2(-speed, rb.velocity.y);
}
break;case EnemyStates.Crawler_Flip:
timer += Time.deltaTime;if(timer > flipWaitTime)
{
timer = 0;
transform.localScale = new Vector2(transform.localScale.x* -1, transform.localScale.y);
ChangeState(EnemyStates.Crawler_Idle);
}break;
}
}
}May 1, 2024 at 12:06 am #14440Joseph TangModerator::If this is the Crawler Enemy, It does not need it’s
Update()
Method.protected override void Update() { base.Update(); if(!isRecoiling) { transform.position=Vector2.MoveTowards (transform.position,new Vector2(PlayerController.Instance.transform.position.x, transform.position.y),speed *Time.deltaTime); } }The rest of the code seems fine. Then if your Crawler looks like the Sprite is backwards, remember to set it’s spriterenderer to flip x.
May 1, 2024 at 8:27 pm #14451EthanParticipant::Ive added the bat and the crawler but am having some issues with the crawler not flipping and facing the player im gonna leave the code down below so i can get some help and fix the issue
CRAWLER:
using System.Collections;
using System.Collections.Generic;
using System.Transactions;
using UnityEngine;public class Crawler : Enemy
{
[SerializeField] private float flipWaitTime;
[SerializeField] private float ledgeCheckX;
[SerializeField] private float ledgeCheckY;
[SerializeField] private LayerMask whatIsGround;
float timer;
// Start is called before the first frame update
protected override void Start()
{
base.Start();
rb.gravityScale = 12.0f;
}protected override void Update()
{
base.Update();
if(!isRecoiling)
{
transform.position=Vector2.MoveTowards
(transform.position,new Vector2(PlayerController.Instance.transform.position.x, transform.position.y),speed *Time.deltaTime);
}
}
protected override void UpdateEnemyStates()
{
if(health <= 0)
{
Death(0.05f);
}switch(GetCurrentEnemyState)
{
case EnemyStates.Crawler_Idle:
Vector3 _ledgeCheckStart = transform.localScale.x > 0 ? new Vector3(ledgeCheckX, 0) : new Vector3(-ledgeCheckX, 0);
Vector2 _wallCheckDir = transform.localScale.x > 0 ? transform.right : -transform.right;if (!Physics2D.Raycast(transform.position + _ledgeCheckStart, Vector2.down, ledgeCheckY, whatIsGround)
|| Physics2D.Raycast(transform.position, _wallCheckDir, ledgeCheckX, whatIsGround))
{
ChangeState(EnemyStates.Crawler_Flip);
}if (transform.localScale.x>0)
{
rb.velocity= new Vector2(speed, rb.velocity.y);
}
else
{
rb.velocity= new Vector2(-speed, rb.velocity.y);
}
break;case EnemyStates.Crawler_Flip:
timer += Time.deltaTime;if(timer > flipWaitTime)
{
timer = 0;
transform.localScale = new Vector2(transform.localScale.x* -1, transform.localScale.y);
ChangeState(EnemyStates.Crawler_Idle);
}break;
}
}
}ENEMY CLASS :
using System.Collections;
using System.Collections.Generic;
using TMPro.EditorUtilities;
using Unity.VisualScripting;
using UnityEngine;public class Enemy : MonoBehaviour
{
[SerializeField] protected float health;
[SerializeField] protected float recoilLength;
[SerializeField] protected float recoilFactor;
[SerializeField] protected bool isRecoiling = false;[SerializeField] protected float speed;
[SerializeField] private float damage;
[SerializeField] protected GameObject orangeBlood;protected float recoilTimer;
protected Rigidbody2D rb;
protected SpriteRenderer sr;
protected Animator anim;protected bool hasTakenDamage = false;
protected EnemyStates currentEnemyState;
protected enum EnemyStates
{
//crawler
Crawler_Idle,
Crawler_Flip,//Bat
Bat_Idle,
Bat_Chase,
Bat_Stunned,
Bat_Death,
}
protected virtual EnemyStates GetCurrentEnemyState
{
get { return currentEnemyState; }
set
{
if(currentEnemyState != value)
{
currentEnemyState = value;ChangeCurrentAnimation();
}
}
}// Start is called before the first frame update
protected virtual void Start()
{
rb = GetComponent<Rigidbody2D>();
sr = GetComponent<SpriteRenderer>();
anim= GetComponent<Animator>();
}
// Update is called once per frame
protected virtual void Update()
{
hasTakenDamage = false;if(isRecoiling)
{
if(recoilTimer < recoilLength)
{
recoilTimer += Time.deltaTime;
}
else
{
isRecoiling = false;
recoilTimer = 0;
}
}
else
{
UpdateEnemyStates();
}
}
public virtual void EnemyHit(float _damageDone, Vector2 _hitDirection, float _hitForce)
{
health -= _damageDone;
if(!isRecoiling )
{
GameObject _orangeBlood = Instantiate(orangeBlood, transform.position,Quaternion.identity);
Destroy(_orangeBlood, 5.5f);
rb.AddForce(-_hitForce * recoilFactor * _hitDirection);
}
}
protected void OnCollisionStay2D(Collision2D _other)
{
if (_other.gameObject.CompareTag(“Player”)&& !PlayerController.Instance.pState.invincible && !PlayerController.Instance.pState.invincible && health>0)
{
Attack();
PlayerController.Instance.HitStopTime(0, 5, 0.5f);
}
}protected virtual void Death(float _destroyTime)
{
Destroy(gameObject, _destroyTime);
}protected virtual void UpdateEnemyStates()
{}
protected virtual void ChangeCurrentAnimation()
{}
protected void ChangeState(EnemyStates _newState)
{
GetCurrentEnemyState = _newState;
}protected virtual void Attack()
{
PlayerController.Instance.TakeDamage(damage);
}
}May 1, 2024 at 10:20 pm #14459Joseph TangModerator::I’ve combined your posts together and deleted the other one.
May i ask if the suggested removal of theUpdate()
in Crawler.cs had any effect?May 1, 2024 at 10:54 pm #14463EthanParticipant::yeah ofcourse , I removed the update code and it made it worse the crawler now doesnt chase me at all and just goes off in one direction
May 1, 2024 at 11:36 pm #14465Joseph TangModerator::Okay, so it works.
If you check the video, the purpose of the Crawler enemy is that it does not chase the player but rather moves back and forth on the ground.
It’s only going to move left and right and cycle through that once it detects that the edge of the ground.
It will not chase the player but can damage the player if they collide.Take a look at the Bat and Charger enemy for something that will chase the player.
The Bat will seek the player out after spotting them. The Charger will patrol the same way as the Crawler but will then speed up at the player when they spot them.May 1, 2024 at 11:44 pm #14466EthanParticipant::I think there is an issue though . It doesnt really go back and fourth it just heads in one direction untill it hits a wall and then doesnt go backwards i can send a video if needed
May 1, 2024 at 11:47 pm #14467Joseph TangModerator::The most likely case is that their detection is not accurate enough, test the enemy out again but on a single platform, like a raised platform or one that is in the air.
Normally, they should be able to detect the edges of the platform. Otherwise, It’s likely they cannot sense the end of a platform due to the box colliders of the platforms they are on being too smoothly connected.
But yes, also send a video on their inspector and scene to show how it is functioning.
May 1, 2024 at 11:58 pm #14468 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: