- Home /
Scrolling texture UV background based on player rotation
I could use some help on scrolling a texture based on the angle a player is facing or turned.
The player is static, does not move, except for rotation on the screen. I have a quad with an image that fills the screen. I have a script attached to this, which is basically supposed to scroll the texture based on the direction the player is facing.
The script for the player is very basic an looks like this
void Update () {
yRot = Input.GetAxis("Horizontal");
xRot = Input.GetAxis("Vertical");
}
private void FixedUpdate()
{
if (yRot != 0 || xRot != 0)
{
angle = Mathf.Atan2(yRot, xRot) * Mathf.Rad2Deg;
quat = Quaternion.Euler(0f, 0f, (-1 * angle));
transform.rotation = Quaternion.Lerp(transform.rotation, quat, rotationSpeed * Time.deltaTime);
}
}
The script attached to the image is where I am having the most issue and really don't know what to do in there. I can get it to just scroll in one direction by doing something like this
void LateUpdate () {
Vector2 OFF = mat.mainTextureOffset; // pull it out to save typing?
OFF.x += 1 * parallax * Time.deltaTime;
OFF.y += 0 * parallax * Time.deltaTime;
mat.mainTextureOffset = OFF;
}
When I try to get the players angle/direction and apply it to the above script, nothing appears to work for me. I am really stumped on this.
I did something similar once, but cannot remember how I got to this method (apart from a lot of hair-pulling and head-desking). So here's an example snippet with the uv scrolling code based on rotation.
// scroll the uvs
float scrollAngle = Vector3.Angle( Vector3.forward, tx.forward );
scrollAngle *= $$anonymous$$athf.Sign( Vector3.Cross( tx.forward, Vector3.forward ).y );
scrollAngle /= 360f;
backgroundRenderer.material.mainTextureOffset = new Vector2( -scrollAngle, 0 );
See the uvs on the background image are different based on my very attractive player character :
That doesn't work for me, dropped it made the small changes I had to make as I am on the Z and not the Y, but it doesn't scroll with these changes.
Ok I think I got something happening, by change the transform.forward to transform.up. But if this is doing what I think it is doing, that is not what I asked for.
Take a sprite in the centre of the screen, it rotates, but I need the UV to scroll in the opposite direction the sprite is facing. Think of it like a spaceship showing top down and if it is facing up the starfield is scrolling down, if the space is facing up and right, then the starfield is scrolling down and left.
If I have this working the way you have give it to me, all it does is scroll the screen on the horizontal if I change direction.
That is a better description of the scenario, I'll see what I can come up with.
I believe I have found my solution, my original way sort of worked, except every now and then it would go what I could only describe as sliding. The reason was because I was using the Angle as it was being calculated via the code. By using the rotation.eualerAngles ins$$anonymous$$d I now have it working, I appreciate the help though. Btw the code you gave, wold that be more suited for something like a defender type style game?
playerAngle = player.rotation.eulerAngles;
direction = new Vector2($$anonymous$$athf.Sin($$anonymous$$athf.Deg2Rad * -playerAngle.z), $$anonymous$$athf.Cos($$anonymous$$athf.Deg2Rad * -playerAngle.z));
offset.x += direction.x * parallaxSpeed * Time.deltaTime;
offset.y += direction.y * parallaxSpeed * Time.deltaTime;
mat.mainTextureOffset = offset;
Answer by AlucardJay · Apr 11, 2018 at 01:30 AM
Get the directional vector of the playerObject rotation :
https://answers.unity.com/questions/251619/rotation-to-direction-vector.html https://answers.unity.com/questions/525952/how-i-can-converting-a-quaternion-to-a-direction-v.html
Apply this vector to the uv offset of the background :
using UnityEngine;
using System.Collections;
public class ScrollUVsOnRotationStarfield : MonoBehaviour
{
public Renderer backgroundRenderer;
public float rotationSpeed = 10f;
public float scrollSpeed = 0.8f;
private Transform tx;
void Start()
{
if ( !backgroundRenderer ) Debug.LogError( gameObject.name + " : backgroundRenderer is not assigned in the Inspector" );
tx = this.transform;
}
void Update()
{
UpdatePlayerShip();
UpdateBackgroundStarfield();
}
void UpdatePlayerShip()
{
// get inputs
float yRot = Input.GetAxis( "Horizontal" );
float xRot = Input.GetAxis("Vertical");
if ( yRot != 0 || xRot != 0 )
{
// rotate this transform
float rotAngle = Mathf.Atan2( yRot, xRot ) * Mathf.Rad2Deg;
Quaternion quat = Quaternion.Euler( 0, 0, -rotAngle );
tx.rotation = Quaternion.Lerp( tx.rotation, quat, rotationSpeed * Time.deltaTime );
}
}
void UpdateBackgroundStarfield()
{
// get directional vector of player
Vector3 playerDir = tx.rotation * Vector3.up;
// determine the scroll directional vector
Vector2 scrollDir = new Vector2( playerDir.x, playerDir.y );
// scroll the background
Vector2 currOffset = backgroundRenderer.material.mainTextureOffset;
backgroundRenderer.material.mainTextureOffset = currOffset + ( scrollDir * scrollSpeed * Time.deltaTime );
}
}
I have accepted this as an answer, even though I found another way to do it. Which I added to the comments above, but will leave it up to others to decide which will suit them.
Again thanks for a solution.
Oh, if this wasn't your solution, you should post yours as an answer (I can accept it for you, but dunno if you get the karma that way). Sorry I didn't really understand your vision, but glad you got it working. All the Best.
That's fine, you went through the trouble of providing another solution and to be honest I think yours looks cleaner.
Your answer
Follow this Question
Related Questions
2D tiled background and scrolling (is this bad?) 1 Answer
So, what's the problem with this code? 1 Answer
Scroll GUI Texture 2 Answers
Offset of texture with Raycast 1 Answer