Unity C# clean,better way to code my feature

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;

public class ActionWander : FSMAction
{
[Header(“Config”)]
[SerializeField] private float enemyMovementSpeed;

[SerializeField] private Vector2 moveRange;

[SerializeField] private EnemyVisual enemyVisual;

[SerializeField] private LayerMask obstacles;

private Vector3 movePosition;
private Rigidbody2D rb;
private CircleCollider2D circleCollider;

private RaycastHit2D raycastDownXLeft;
private RaycastHit2D raycastUpXLeft;
private RaycastHit2D raycastDownXRight;
private RaycastHit2D raycastUpXRight;
private RaycastHit2D raycastLeftYDown;
private RaycastHit2D raycastRightYDown;
private RaycastHit2D raycastLeftYUp;
private RaycastHit2D raycastRightYUp;

private Vector3 movement;
private Vector3 moveDirection;

private float wanderTime;

Vector3 positionAfterCollision;
private float timer;

float randomX;
float randomY;
private bool directionLeft;
private bool collided;
private bool directionUp;

private bool isWalking;

void Awake()
{

collided = false;
rb = GetComponent();
circleCollider = GetComponent();
isWalking = false;
}
void Start()
{
GetNewDestination();
}

void Update()
{
}

//Reffers to Finite State Machine
public override void Act()
{
timer -= Time.deltaTime;
moveDirection = (movePosition - transform.position).normalized;
movement = moveDirection * (enemyMovementSpeed * Time.deltaTime);
if (Vector3.Distance(transform.position, movePosition) >= 0.2f)
{
isWalking = true;
rb.MovePosition(Vector3.MoveTowards(transform.position, movePosition, 0.1f));

}
else
{
isWalking = false;
}

if (timer <= 0f)
{
GetNewDestination();
timer = Random.Range(1f, 5f);
}
enemyVisual.SetWalkingAnimation(isWalking);
}

//Getting new random Dest, when the timer is 0
private void GetNewDestination()
{
randomX = Random.Range(-moveRange.x+0.5f, moveRange.x-0.5f);
if (randomX >= 0)
{
randomX += 0.5f;
}
else
{
randomX -= 0.5f;
}

randomY = Random.Range(-moveRange.y + 0.5f, moveRange.y - 0.5f);
if (randomY >= 0)
{
randomY += 0.5f;
}
else
{
randomY -= 0.5f;
}

//if the enemies are hitting the obstacles, they go away from the obcstacle
//2 raycast per side - because if it is cast just in the middle, sometimes the middle ray is not enough for “if fit in there”
raycastDownXLeft = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - 0.3f), Vector2.left, 2f, obstacles);
raycastUpXLeft = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y + 0.3f), Vector2.left, 2f, obstacles);
raycastDownXRight = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - 0.3f), Vector2.right, 2f, obstacles);
raycastUpXRight = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y + 0.3f), Vector2.right, 2f, obstacles);
raycastLeftYUp = Physics2D.Raycast(new Vector2(transform.position.x - 0.3f, transform.position.y), Vector2.up, 2f, obstacles);
raycastRightYUp = Physics2D.Raycast(new Vector2(transform.position.x + 0.3f, transform.position.y), Vector2.up, 2f, obstacles);
raycastLeftYDown = Physics2D.Raycast(new Vector2(transform.position.x - 0.3f, transform.position.y), Vector2.down, 2f, obstacles);
raycastRightYDown = Physics2D.Raycast(new Vector2(transform.position.x + 0.3f, transform.position.y), Vector2.down, 2f, obstacles);

bool hitDownXLeft = raycastDownXLeft;
bool hitUpXLeft = raycastUpXLeft;
if (hitUpXLeft || hitDownXLeft)
{

randomX = ChangeXPositionToRight();
Debug.Log(“HITUJE LEFT”);
}

bool hitDownXRight = raycastDownXRight;
bool hitUpXRight = raycastUpXRight;
if (hitDownXRight || hitUpXRight)
{
randomX = ChangeXPositionToleft();
Debug.Log(“HITUJE RIGHT”);
}

bool hitLeftYUp = raycastLeftYUp;
bool hitRightYUp = raycastRightYUp;
if (hitLeftYUp || hitRightYUp)
{
randomY = ChangeYPositionToDown();
Debug.Log(“HITUJE UP”);
}

bool hitLeftYDown = raycastLeftYDown;
bool hitRightYDown = raycastRightYDown;
if (hitLeftYDown || hitRightYDown)
{
randomY = ChangeYPositionToUp();
Debug.Log(“HITUJE DOWN”);
}

//if obstacle is on LEFT and RIGHT, just move only up and down
if (hitDownXLeft && hitDownXRight || hitUpXLeft && hitUpXRight)
{
randomX = 0;
}

//if obstacles is on UP and DOWN, just move only left and right
if (hitLeftYDown && hitLeftYUp || hitRightYDown && hitRightYUp)
{
randomY = 0;
}

movePosition = transform.position + new Vector3(randomX, randomY);

}

//if obstacles is on left, change to right
private float ChangeXPositionToRight()
{
// Debug.Log(“CHANGE TO RIGHT”);
directionLeft = false;
float changeXRightPosition = Random.Range(0.5f, moveRange.x);
return changeXRightPosition;

}

//if obstacles is on right, change to left
private float ChangeXPositionToleft()
{
// Debug.Log(“CHANGE TO LEFT”);
directionLeft = true;
float changeXLeftPosition = Random.Range(-moveRange.x, -0.5f);
return changeXLeftPosition;

}

//if obstacles is on up, change to down
private float ChangeYPositionToDown()
{
// Debug.Log(“CHANGE TO DOWN”);
directionUp = false;
float changeYDownPosition = Random.Range(-moveRange.y, -0.5f);
return changeYDownPosition;

}

//if obstacles is on down, change to up
private float ChangeYPositionToUp()
{
// Debug.Log(“CHANGE TO UP”);
directionUp = true;
float changeYUpPosition = Random.Range(0.5f, moveRange.y);
return changeYUpPosition;

}

private void OnDrawGizmosSelected()
{
if (moveRange != Vector2.zero)
{
Gizmos.color = Color.black;
Gizmos.DrawWireCube(transform.position, moveRange * 2f);
Gizmos.DrawLine(transform.position, movePosition);
}
}

private void OnCollisionEnter2D(Collision2D collision)
{
moveDirection = transform.position;
isWalking = false;

}

}

my answer is - How it could be in better, clean and more professional way?
Another thing, I am trying 2 day make enemy stop moving when they hit the obstacle, because now they are stucking and try to move into the obstacles…
I tried make rb.MovePosition, didnt work, I tried make if finalDestination is in obstacle, it doesnt run. But it would be soo hard because I have to make refenreces of every object? I can do the animation - isWalking true/false. and if they hit the obstacle, they change the animation… But I cant figure out how to stop moving. If I use collidersEnter, when the enemy hit the obstacle, it will always oncollided, so it never move again… Thank you:)

For starters you could use code tags. :stuck_out_tongue:

https://discussions.unity.com/t/481379

8 Likes
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;

public class ActionWander : FSMAction
{
[Header(“Config”)]
[SerializeField] private float enemyMovementSpeed;


[SerializeField] private Vector2 moveRange;

[SerializeField] private EnemyVisual enemyVisual;

[SerializeField] private LayerMask obstacles;

private Vector3 movePosition;
private Rigidbody2D rb;
private CircleCollider2D circleCollider;

private RaycastHit2D raycastDownXLeft;
private RaycastHit2D raycastUpXLeft;
private RaycastHit2D raycastDownXRight;
private RaycastHit2D raycastUpXRight;
private RaycastHit2D raycastLeftYDown;
private RaycastHit2D raycastRightYDown;
private RaycastHit2D raycastLeftYUp;
private RaycastHit2D raycastRightYUp;

private Vector3 movement;
private Vector3 moveDirection;

private float wanderTime;

Vector3 positionAfterCollision;
private float timer;

float randomX;
float randomY;
private bool directionLeft;
private bool collided;
private bool directionUp;


private bool isWalking;

void Awake()
{

collided = false;
rb = GetComponent<Rigidbody2D>();
circleCollider = GetComponent<CircleCollider2D>();
isWalking = false;
}
void Start()
{
GetNewDestination();
}

void Update()
{
}

//Reffers to Finite State Machine
public override void Act()
{
timer -= Time.deltaTime;
moveDirection = (movePosition - transform.position).normalized;
movement = moveDirection * (enemyMovementSpeed * Time.deltaTime);
if (Vector3.Distance(transform.position, movePosition) >= 0.2f)
{
isWalking = true;
rb.MovePosition(Vector3.MoveTowards(transform.position, movePosition, 0.1f));

}
else
{
isWalking = false;
}

if (timer <= 0f)
{
GetNewDestination();
timer = Random.Range(1f, 5f);
}
enemyVisual.SetWalkingAnimation(isWalking);
}


//Getting new random Dest, when the timer is 0
private void GetNewDestination()
{
randomX = Random.Range(-moveRange.x+0.5f, moveRange.x-0.5f);
if (randomX >= 0)
{
randomX += 0.5f;
}
else
{
randomX -= 0.5f;
}

randomY = Random.Range(-moveRange.y + 0.5f, moveRange.y - 0.5f);
if (randomY >= 0)
{
randomY += 0.5f;
}
else
{
randomY -= 0.5f;
}

//if the enemies are hitting the obstacles, they go away from the obcstacle
//2 raycast per side - because if it is cast just in the middle, sometimes the middle ray is not enough for "if fit in there"
raycastDownXLeft = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - 0.3f), Vector2.left, 2f, obstacles);
raycastUpXLeft = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y + 0.3f), Vector2.left, 2f, obstacles);
raycastDownXRight = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y - 0.3f), Vector2.right, 2f, obstacles);
raycastUpXRight = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y + 0.3f), Vector2.right, 2f, obstacles);
raycastLeftYUp = Physics2D.Raycast(new Vector2(transform.position.x - 0.3f, transform.position.y), Vector2.up, 2f, obstacles);
raycastRightYUp = Physics2D.Raycast(new Vector2(transform.position.x + 0.3f, transform.position.y), Vector2.up, 2f, obstacles);
raycastLeftYDown = Physics2D.Raycast(new Vector2(transform.position.x - 0.3f, transform.position.y), Vector2.down, 2f, obstacles);
raycastRightYDown = Physics2D.Raycast(new Vector2(transform.position.x + 0.3f, transform.position.y), Vector2.down, 2f, obstacles);



bool hitDownXLeft = raycastDownXLeft;
bool hitUpXLeft = raycastUpXLeft;
if (hitUpXLeft || hitDownXLeft)
{

randomX = ChangeXPositionToRight();
Debug.Log("HITUJE LEFT");
}


bool hitDownXRight = raycastDownXRight;
bool hitUpXRight = raycastUpXRight;
if (hitDownXRight || hitUpXRight)
{
randomX = ChangeXPositionToleft();
Debug.Log("HITUJE RIGHT");
}



bool hitLeftYUp = raycastLeftYUp;
bool hitRightYUp = raycastRightYUp;
if (hitLeftYUp || hitRightYUp)
{
randomY = ChangeYPositionToDown();
Debug.Log("HITUJE UP");
}



bool hitLeftYDown = raycastLeftYDown;
bool hitRightYDown = raycastRightYDown;
if (hitLeftYDown || hitRightYDown)
{
randomY = ChangeYPositionToUp();
Debug.Log("HITUJE DOWN");
}


//if obstacle is on LEFT and RIGHT, just move only up and down
if (hitDownXLeft && hitDownXRight || hitUpXLeft && hitUpXRight)
{
randomX = 0;
}

//if obstacles is on UP and DOWN, just move only left and right
if (hitLeftYDown && hitLeftYUp || hitRightYDown && hitRightYUp)
{
randomY = 0;
}



movePosition = transform.position + new Vector3(randomX, randomY);



}

//if obstacles is on left, change to right
private float ChangeXPositionToRight()
{
// Debug.Log("CHANGE TO RIGHT");
directionLeft = false;
float changeXRightPosition = Random.Range(0.5f, moveRange.x);
return changeXRightPosition;


}

//if obstacles is on right, change to left
private float ChangeXPositionToleft()
{
// Debug.Log("CHANGE TO LEFT");
directionLeft = true;
float changeXLeftPosition = Random.Range(-moveRange.x, -0.5f);
return changeXLeftPosition;

}

//if obstacles is on up, change to down
private float ChangeYPositionToDown()
{
// Debug.Log("CHANGE TO DOWN");
directionUp = false;
float changeYDownPosition = Random.Range(-moveRange.y, -0.5f);
return changeYDownPosition;

}

//if obstacles is on down, change to up
private float ChangeYPositionToUp()
{
// Debug.Log("CHANGE TO UP");
directionUp = true;
float changeYUpPosition = Random.Range(0.5f, moveRange.y);
return changeYUpPosition;

}

private void OnDrawGizmosSelected()
{
if (moveRange != Vector2.zero)
{
Gizmos.color = Color.black;
Gizmos.DrawWireCube(transform.position, moveRange * 2f);
Gizmos.DrawLine(transform.position, movePosition);
}
}

private void OnCollisionEnter2D(Collision2D collision)
{
moveDirection = transform.position;
isWalking = false;


}

}

Rather than posting walls of code and paragraphs of questions and “better way to code my feature,” try this approach:

How to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, log output, variable values, and especially any errors you see
  • links to actual Unity3D documentation you used to cross-check your work (CRITICAL!!!)

The purpose of YOU providing links is to make our job easier, while simultaneously showing us that you actually put effort into the process. If you haven’t put effort into finding the documentation, why should we bother putting effort into replying?

2 Likes