Hello there, it’s me again. I managed now to attach a spotlight to the player, but it’s only facing in one direction. I want it’s rotation to change relative to the mouse position, so that it is not limited to 4 set angles. I only found solutions for 3D projects. Can I use eulerAngles for this? I tried .Rotate but it’s apparently not what I need, since that literally just rotates the light 1fps in one direction…
Can you share the code that you tried? You definitely can use Rotate, you may not be using the correct parameters.
If you want the light to rotate to point at the mouse location, you’ll need to rotate the light about the Z axis.
This code will point an object at the mouse cursor’s position in 2D:
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = transform.position.z;
Quaternion targetRotation = Quaternion.LookRotation(Vector3.forward, mousePos - transform.position);
// use this line for instant-rotation
transform.rotation = targetRotation;
// use this line for rotation over time
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeedFloat);
Notice this keeps the mouse position’s Z value equal to the current object’s Z value, so it will keep the light aligned to the XY plane. If you need the object tilted, you can add or subtract from the Z value being assigned to mousePos.z, or use this script on a parent object of the light, and angle the light however you wish.
Sorry, I just realized what I said was stupid. But what I actually mean is that I want my light to shine from the player to the floor. Right now the player basically stands in a spotlight. I can see it rotating to wherever I put my mouse, but it doesn’t look like a flashlight yet.
For simplicity and keeping the code reusable and modular, I would recommend not changing the code, and creating an empty GameObject to apply this script to, and then you can manually rotate the light as the child and it will keep that rotation relative to the parent.
(You could make a “LookAtMouse” component and reuse it in the future).
However you can alter the script to set that rotational offset as well. Since you want to add a rotation in degrees, we have to use EulerAngles to get those values. Then you can alter the targetRotation like so:
public float yAngle = 35f;
public float rotationSpeed = 5f;
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
mousePos.z = transform.position.z;
Quaternion targetRotation = Quaternion.LookRotation(Vector3.forward, mousePos - transform.position);
Vector3 newEulers = targetRotation.eulerAngles;
newEulers.y = yAngle;
targetRotation.eulerAngles = newEulers;
// use this line for instant-rotation
transform.rotation = targetRotation;
// use this line for rotation over time
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed);
One thing to note is that this script will point the X axis towards the mouse I believe. Spot lights by default point down the -Y axis I believe. Just something to be aware of.
Do you think I could set the newEulers to transformed positions of mousePos ? My problem right now is that (of course) if I set y to 35 it stays on one side. But what I’m working on is kind of like an RPG in Zelda style, which means that the flashlight has to go around the player, but I don’t want its range to change. Here’s a picture of my game scene. Basically what you see in the game view is what I want it to look like and the player should only be able to change the direction the light is pointing. I’m sorry if I ask very basic questions, but I hope this makes it clearer.
No unfortunately not. This is what the code looks like. Am I missing something?
using UnityEngine;
using System.Collections;
public class Flashlight : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Vector3 mousePos = Camera.main.ScreenToWorldPoint (Input.mousePosition);
mousePos.z = transform.position.z;
Quaternion targetRotation = Quaternion.LookRotation (Vector3.forward, mousePos - transform.position);
transform.rotation = targetRotation;
}
}
Looking at your screenshot, you have the “Flashlight” script on the “Spotlight” object. Put it on the “LookAtMouse” object so that the Spotlight isn’t rotating at all via script. Only the parent rotates, the Spotlight keeps it’s orientation relative to the parent.
I’ve removed the Flashlight script from the Spotlight and put it on the LookAtMouse object instead. The light rotates around some spot on the map instead of seeing the player as a “source” and sending light from there.
Make sure your flashlight is at position 0,0,0 underneath the “LookAtMouse” object, and your “LookAtMouse” object is also at position 0,0,0 underneath the player.
Here’s an updated version of the script that will point the X axis at the mouse. This is usually what 2D objects consider the forward facing axis.
using UnityEngine;
public class LookAtMouse : MonoBehaviour {
private void LateUpdate () {
// get the mouse position in world space
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// change mouse Z position equal to this object's
mousePos.z = transform.position.z;
// get a rotation that points Z axis forward, and the Y axis towards the target
Quaternion targetRotation = Quaternion.LookRotation(Vector3.forward, (mousePos - transform.position));
// apply new rotation
transform.rotation = targetRotation;
// rotate 90 degrees around the Z axis to point X axis instead of Y
transform.Rotate(0, 0, 90);
}
}
I am a total newbie. Omg thanks I been looking for something like this. One thing though I dont quite understand euler’s how are you making it rotate via the x axis?
Being a 2D game, just about all rotations happen around the Z axis. The Z axis is the direction the camera is facing, it’s the depth axis.
The “LookRotation” function can take two parameters, the Z axis direction, and the Y axis direction. What this does is creates a rotation in which both of those axes are pointing in the directions I supplied.
You can think of a direction as a line pointing from the origin (0,0,0), to the (X,Y, Z) point given.
For the Z axis, I gave it “Vector3.forward” which means the same as (0,0,1), which is the world Z axis direction. So the Z axis of the sprite keeps pointing forward, and making the sprite face the camera and stay parallel to the XY plane.
Then I gave it the Y axis in the direction which points from the player to the mouse position by doing a little vector subtraction (mousePos - transform.position). The resulting vector is the direction FROM transform.position TO mousePos.
So that results in the Y axis pointing at the mouse, and the Z axis staying pointing forward.
Here’s the important bit:
Most of the time you want the X axis to be the direction a sprite is facing. The X axis is always at a right angle, 90 degrees away from the Y axis. So after the “LookRotation” does its thing, I rotate it around the Z axis by an additional 90 degrees, so that the X axis is where the Y axis used to be.