Made some good progress using Raycasts, had to first figure out how to only apply it to 2 of my LayerMasks, then noticed that it actually takes that as a 4th argument!
So now I’ve tied the laser eyeball weapon (sprite/animation for it not started yet!) to my player character with one script, which controls it’s activation and how long it stays on the player, until it’s destroyed, then it’ll pop back up again after 3 seconds.
In another script I control the functionality of the laser itself and the way in which it damages the enemies.
I still have 2 remaining issues, that are illustrated in the video below:
cornysophisticatedaustraliancattledog
1.) When the Ray is cast but it’s not hitting any collider, it falls into an else block for the LineRenderer to be drawn to it’s full distance. If it is hitting something, the Line Renderer will stop at the point of collision. However when it’s not hitting any collider and my player is moving, the line is not going straight horizontally in the correct direction, it starts moving up or down depending on my players movement. I believe it’s something perhaps at line 50 of the code below that’s causing the issue
2.) When I’ve hit an enemy, the enemy turns red. However I want to put the enemy back to it’s normal color when it’s no longer being hit. I’ve tried to put some code in for this at line 52 of the code below, however the code I’ve got is saying “If we have a spriteRenderer stored from the last hit, but there’s no hit, then return that enemy back to normal (not red)”, however if I move the lazer from one enemy to another straight away, the last enemy will remain red. It’s like I need to compare the old collision to the new one and see if they are different, if they are, return the old enemy back to normal color, not quite sure how to achieve this though.
Below is the code I’m using for the laser logic:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class EyeballLogic : MonoBehaviour
{
[SerializeField] private float defDistanceRay;
public LineRenderer lineRenderer;
public Transform EyeballFirePoint;
Transform EyeballTransform;
[SerializeField] private LayerMask EnemyHitboxLayerMask;
[SerializeField] private LayerMask EnemyPusherLayerMask;
[SerializeField] private int damage;
[SerializeField] private Transform pfDamageIndicator;
private SpriteRenderer spriteOfenemy;
private PlayerMovement player;
private Vector3 facingRight;
private Vector3 facingLeft;
float timer = 0f;
private void Start() {
player = GetComponentInParent<PlayerMovement>();
facingRight = new Vector3(1,0,0);
facingLeft = new Vector3(-1,0,0);
}
private void Update() {
Vector3 directionToFire = player.facingRight ? facingRight : facingLeft;
ShootLaser(directionToFire);
}
void ShootLaser(Vector3 directionToFire) {
if (Physics2D.Raycast(EyeballFirePoint.position, directionToFire, 100, EnemyHitboxLayerMask | EnemyPusherLayerMask)) {
RaycastHit2D hit = Physics2D.Raycast(EyeballFirePoint.position, directionToFire, 100, EnemyHitboxLayerMask | EnemyPusherLayerMask);
Draw2DRay(EyeballFirePoint.position, hit.point);
if (timer > 0f) {
timer -= Time.deltaTime;
}
if (timer <= 0f) {
DamageEnemy(hit);
}
}
else {
Draw2DRay(EyeballFirePoint.position, directionToFire * 100);
if (spriteOfenemy) {
ChangeEnemyBackToNormalColor();
}
}
}
void Draw2DRay(Vector2 startPos, Vector2 endPos) {
lineRenderer.SetPosition(0, startPos);
lineRenderer.SetPosition(1, endPos);
}
void DamageEnemy(RaycastHit2D hit) {
if (hit.collider) {
StandardEnemyMovement enemyLogic = hit.collider.GetComponentInParent<StandardEnemyMovement>();
enemyLogic.health = enemyLogic.health - damage;
TextMeshPro textMesh = pfDamageIndicator.GetComponent<TextMeshPro>();
textMesh.SetText(damage.ToString());
Instantiate(pfDamageIndicator, hit.transform.position, Quaternion.identity);
spriteOfenemy = hit.collider.GetComponentInParent<SpriteRenderer>();
spriteOfenemy.color = new Color(184, 0, 0, 255);
timer = 0.3f;
}
}
void ChangeEnemyBackToNormalColor() {
spriteOfenemy.color = new Color(255, 255, 255, 255);
spriteOfenemy = null;
}
}
EDIT: Issue 2.) has now been fixed I did:
void DamageEnemy(RaycastHit2D hit) {
if (hit.collider) {
StandardEnemyMovement enemyLogic = hit.collider.GetComponentInParent<StandardEnemyMovement>();
enemyLogic.health = enemyLogic.health - damage;
TextMeshPro textMesh = pfDamageIndicator.GetComponent<TextMeshPro>();
textMesh.SetText(damage.ToString());
Instantiate(pfDamageIndicator, hit.transform.position, Quaternion.identity);
if (spriteOfEnemy != null && spriteOfEnemy != hit.collider.GetComponentInParent<SpriteRenderer>()) {
spriteOfEnemy.color = new Color(255, 255, 255, 255);
}
spriteOfEnemy = hit.collider.GetComponentInParent<SpriteRenderer>();
spriteOfEnemy.color = new Color(184, 0, 0, 255);
timer = 0.3f;
}
}
So, if we have a sprite of the enemy and the new one being hit is not the same as the old one, put it’s color back to normal from red.
EDIT: Issue 1.) has now been fixed I did:
void ShootLaster(Vector3 directionToFire) {
if (Physics2D.Raycast(EyeballFirePoint.position, directionToFire, 50, EnemyHitboxLayerMask | EnemyPusherLayerMask)) {
RaycastHit2D hit = Physics2D.Raycast(EyeballFirePoint.position, directionToFire, 50, EnemyHitboxLayerMask | EnemyPusherLayerMask);
Draw2DRay(EyeballFirePoint.position, hit.point);
if (timer > 0f) {
timer -= Time.deltaTime;
}
if (timer <= 0f) {
DamageEnemy(hit);
}
}
else {
Draw2DRay(EyeballFirePoint.position, new Vector2(player.facingRight ? EyeballFirePoint.position.x + 50 : EyeballFirePoint.position.x -50, EyeballFirePoint.position.y));
if (spriteOfEnemy) {
ChangeEnemyBackToNormalColor();
}
}
}
void Draw2DRay(Vector2 startPos, Vector2 endPos) {
Debug.Log(endPos);
lineRenderer.SetPosition(0, startPos);
lineRenderer.SetPosition(1, endPos);
}
Had to tinker around with the Vector2 I passed as the end position to the Draw2Ray function. Had to take a break from it, as i was just trying to force stuff to work and not actually thinking about the problem.