I have a few example gifs shown below. I am not sure exactly why this is happening but hopefully they help. My code is below the gifs.
Thanks in advance for any help that can be provided!!! I’m also happy to answer any questions.
-
Here you can see how the speed of my projectiles increase as I aim further away from the player.
-
When I move my player away from (0, 0) on the map, the projectiles stop flying towards my cursor the further I aim to the left of right, but still move correctly if I aim exactly up or down.
-
Finally, if I move to the corner of my map so neither coordinate is 0, the projectiles are strongly biased towards my direction relative to the map center. They only fly straight when my “aim” vector lines up with my “player-map” vector.
Script to aim the wand towards the player mouse:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAimWand : MonoBehaviour
{
public event EventHandler<OnShootEventArgs> OnShoot;
public class OnShootEventArgs : EventArgs {
public Vector3 wandEndpointPosition;
public Vector3 shootPosition;
}
public Transform aimTransform;
public Animator wandAnimator;
public SpriteRenderer wandRenderer;
private Transform aimWandEndPointTransform;
private void Awake() {
aimWandEndPointTransform = aimTransform.Find("WandEndPoint");
wandAnimator = wandRenderer.GetComponent<Animator>();
}
void Update()
{
HandleAiming();
HandleShooting();
}
private void SetWandLayerOrder(float angle) {
if (angle >=0) {
wandRenderer.GetComponent<SpriteRenderer>().sortingOrder = 0;
} else {
wandRenderer.GetComponent<Renderer>().sortingOrder = 2;
}
}
private void HandleAiming() {
float angle = Utils.GetMouseAngle(transform) * Mathf.Rad2Deg;
aimTransform.eulerAngles = new Vector3(0, 0, angle);
SetWandLayerOrder(angle);
}
private void HandleShooting() {
if (Input.GetMouseButtonDown(0)) {
Vector3 mousePosition = Utils.GetMouseWorldPosition();
// Shoot!
wandAnimator.SetTrigger("Shoot");
OnShoot?.Invoke(this, new OnShootEventArgs {
wandEndpointPosition = aimWandEndPointTransform.position,
shootPosition = mousePosition,
});
}
}
}
Script to fire the projectile:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerShootProjectiles : MonoBehaviour
{
[SerializeField] private Transform pfBullet;
private void Awake() {
GetComponent<PlayerAimWand>().OnShoot += PlayerAimWand_OnShoot;
}
private void PlayerAimWand_OnShoot(object sender, PlayerAimWand.OnShootEventArgs e) {
Transform spellTransform = Instantiate(pfBullet, e.wandEndpointPosition, Quaternion.identity);
Vector3 shootDir = e.shootPosition - e.wandEndpointPosition.normalized;
spellTransform.GetComponent<Projectile>().Setup(shootDir);
}
}
Script to instantiate a projectile instance:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : MonoBehaviour
{
public float projectileSpeed = 1f;
public float lifetime = 6f;
private Vector3 shootDir;
public void Setup(Vector3 shootDir) {
this.shootDir = shootDir;
transform.eulerAngles = new Vector3(0, 0, Utils.GetAngleFromVectorFloat(shootDir));
Debug.Log(Utils.GetAngleFromVectorFloat(shootDir));
}
private void Awake () {
Destroy(gameObject, lifetime);
}
private void Update() {
Debug.Log("shootdir: " + shootDir);
//Debug.Log("Time.deltaTime: " + Time.deltaTime);
Debug.Log("projectileSpeed: " + projectileSpeed);
transform.position += shootDir * Time.deltaTime * projectileSpeed;
}
}
Edit: One additional script I forgot to include that I use here is how I get my mouse position:
// Get Mouse Position in World with Z = 0f
public static Vector3 GetMouseWorldPosition() {
Vector3 vec = GetMouseWorldPositionWithZ(Input.mousePosition, Camera.main);
vec.z = 0f;
return vec;
}
public static Vector3 GetMouseWorldPositionWithZ() {
return GetMouseWorldPositionWithZ(Input.mousePosition, Camera.main);
}
public static Vector3 GetMouseWorldPositionWithZ(Camera worldCamera) {
return GetMouseWorldPositionWithZ(Input.mousePosition, worldCamera);
}
public static Vector3 GetMouseWorldPositionWithZ(Vector3 screenPosition, Camera worldCamera) {
Vector3 worldPosition = worldCamera.ScreenToWorldPoint(screenPosition);
return worldPosition;
}