- Home /
Quaternion rotation triggers change in Texture
Hello All
I have a stationary plane that faces the player
As the player moves around it (360 Degrees) I need the texture to change.
So it's as if I had taken 16 pictures around an object, the texture would change relative to the players position and it would seem like a 360 "object"
Here is the C# code. Rotations are working Quaternions are moving I just can't track the numbers correctly to use if statements to control the texture switching.
using UnityEngine;
using System.Collections;
public class LookAt : MonoBehaviour {
public Transform player;
// Here are the 16 textures I manually assign:
public Texture Texture1;
public Texture Texture2;
public Texture Texture3;
public Texture Texture4;
public Texture Texture5;
public Texture Texture6;
public Texture Texture7;
public Texture Texture8;
public Texture Texture9;
public Texture Texture10;
public Texture Texture11;
public Texture Texture12;
// etc etc
void Start()
{
player = GameObject.Find ("Player").transform;
}
void Update()
{
// Plane faces the Player
Vector3 v3 = player.position - transform.position;
v3.y = 0.0f;
transform.rotation = Quaternion.LookRotation(-v3);
// Sending the transform.rotation to the console in hopes of finding something I could use...
Debug.Log (transform.rotation);
// Calls the method fot changing texture.
ChangeTexture();
}
void ChangeTexture()
// What I want to do is every 20 degrees switch the texture
// if the plane is rotated 0 - 20 deg use texture 1
// if the plane is rotated 20 - 40 deg use texture 2 etc
{
if (transform.rotation.y != 0) {
GetComponent<Renderer>().material.mainTexture = Texture2;
}
}
}
I appreciate your looking !
~be
You should probably be using uv-changes and a texture atlas (sprite sheet) for this job.
Even using this individual-textures method, you'd be better of storing them in an ordered collection so you can select them programmatically. As it stands, you'll need a switch or conditional check per rotation range / texture. If they were in an array ins$$anonymous$$d, you could use some simple math to deter$$anonymous$$e which to use.
The fastest solution will be a custom shader with cubemaps
@AlwaysSunny I have tried this solution, and it works but is jaggy and doesn't work on mobile (may start a new thread on that
@Itaros I have no idea where to begin with cube map shaders : o
Answer by robertbu · Nov 04, 2014 at 07:49 AM
Note for every 20 degrees, you need 18 images. You should put them in an array. You can get the index by:
float angle = Mathf.Atan2(Camera.main.transform.forward.y, Camera.main.transform.forward.z) * Mathf.Rad2Deg;
int index = angle / imageCount;
renderer.material.mainTexture = textures[index];
...where 'imageCount' is the number of images in your array.
robertBu! Thank you ! But I'm still a bit confused.
Here's the new code:
public class LookAt : $$anonymous$$onoBehaviour {
public Transform player;
// declare array
public Texture[] imageCount;
// Here are the 16 textures I manually assign:
public Texture Texture1;
public Texture Texture2;
public Texture Texture3;
public Texture Texture4;
public Texture Texture5;
public Texture Texture6;
public Texture Texture7;
public Texture Texture8;
public Texture Texture9;
public Texture Texture10;
public Texture Texture11;
public Texture Texture12;
public Texture Texture13;
public Texture Texture14;
public Texture Texture15;
public Texture Texture16;
void Start()
{
player = GameObject.Find ("Player").transform;
}
void Update()
{
// Plane faces the Player
Vector3 v3 = player.position - transform.position;
v3.y = 0.0f;
transform.rotation = Quaternion.LookRotation(-v3);
// Sending the transform.rotation to the console in hopes of finding something I could use...
Debug.Log (transform.rotation);
// Calls the method fot changing texture.
ChangeTexture();
}
void ChangeTexture()
// What I want to do is every 20 degrees switch the texture
// if the plane is rotated 0 - 20 deg use texture 1
// if the plane is rotated 20 - 40 deg use texture 2 etc
{
var angle = $$anonymous$$athf.Atan2(Camera.main.transform.forward.y, Camera.main.transform.forward.x) * $$anonymous$$athf.Rad2Deg;
var index = angle/imageCount;
GetComponent<Renderer>().material.mainTexture = textures[index];
}
}
Line 2 of your code ( var index = angle/imageCount;) gives me the error:
Assets/Scripts/LookAt.cs(63,29): error CS0019: Operator /' cannot be applied to operands of type
float' and `UnityEngine.Texture[]'
I appreciate your help!
~be
First off, you need your textures in an array:
public Texture[] textures;
Delete lines 9 - 24. Then set the size of 'textures' in the inspector and drag and drop them into the array. You will have to play a bit to get the order right for the rotation.
'imageCount' would be an integer representing the number of images in the array, but it would be better done this way:
float angle = $$anonymous$$athf.Atan2(Camera.main.transform.forward.y, Camera.main.transform.forward.z) * $$anonymous$$athf.Rad2Deg;
if (angle < 0)
angle = 360.0f - angle;
int index = (int)angle/textures.Length;
renderer.material.mainTexture = textures[index];
Thank you RobertBu getting closer - while I don't have any errors, the textures don't change
(I have assigned them properly in the inspector)
The Beta for Unity insists on changing the last line of your code to :
void ChangeTexture()
{
float angle = $$anonymous$$athf.Atan2(Camera.main.transform.forward.y, Camera.main.transform.forward.z) * $$anonymous$$athf.Rad2Deg;
int index = (int)angle/textures.Length;
GetComponent<Renderer>().material.mainTexture = textures[index];
}
}
While it runs, it doesn't change texture because they are " Out of range"...
This is the error in the console:
IndexOutOfRangeException: Array index is out of range.
LookAt.ChangeTexture () (at Assets/Scripts/LookAt.cs:65)
LookAt.Update () (at Assets/Scripts/LookAt.cs:51)
Thanks for you help!
~be
To me FPS means First Person Shooter, which means the camera. Taking a look at what you've written here, you probably want the angle generated by the vector between the player and your object:
void ChangeTexture()
{
Vector3 dir = player.position - transform.position;
float angle = $$anonymous$$athf.Atan2(dir.y, dir.z) * $$anonymous$$athf.Rad2Deg;
int index = (int)angle/textures.Length;
GetComponent<Renderer>().material.mainTexture = textures[index];
}