So I’ve had a little search after getting a message “Look rotation viewing vector is zero”, the solutions/common fix is do an if != vector3.zero, but i’m in the center of the sphere (VR based warblings) and I want the objects I’ve placed around me to face the center.
I have debug lines draw correctly all pointing from object to center, but I have an error look rotation viewing is Zero, what if I want to look at an object that happens to lie on 0,0,0?
Slightly confused, anyone have any ideas?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rotater : MonoBehaviour
{
bool hasStarted = false;
public Transform targetTransform;
void Update ()
{
targetTransform = GameObject.Find("Cube").transform;
if (hasStarted == false)
{
Vector3 relativePos = targetTransform.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(relativePos);
Debug.DrawRay(transform.position, relativePos, Color.red);
float lookTowardsX = rotation.eulerAngles.x;
float lookTowardsZ = rotation.eulerAngles.z;
//this.gameObject.transform.LookAt(Vector3.zero);
transform.rotation = rotation;
hasStarted = true;
}
}
}
Just did some debug lines for Relative position and position and seems they are cancelling out into zero, ie pos(0,8,0), relPos(0,-8,0), so the number in the Quat lookRotation turns into zero.
Direction vector has the total length of 1. If it has something else, it is not a direction vector, but something else. If you want to make a direction vector from just “length+direction” vector (when the total length > or < 1), you need to normalise it. When two points cancel out each other, then it does not mean that dir vector is zero. It means that the vector is aimed straight to the right (1, 0, 0).
tried to normalise the relPos vector like you said, not sure what’s it’s done but the debug lines now show a different value to pos, not the inverse as without normalizing.
thanks for the edit, I think that clears it up a bit conceptually, would i need to normalise both the relative position and the normal position for it to work?
I just thought. It is not about cancelation 100%. They cannot cancel each other anyhow, except they have the same position. i.e. y2 - y1 = 8 - (-8) = 16, but not 0.
They probably look at the centre, but not as you want. I mean that the face side of the object is not the same as you want it to be. For example, if we have a person. His face side will be obviously his face. So, it represents Z axis (blue arrow).
If Z axis would be represented by, for example, right hand side, then computer would think that the face side is his hand. And then if I would make LookRotation towards the object, then the player’s hand would be directed towards the object, but not his face. (Really hope you understood what I mean. I dont know how to explain that properly ). So, what you can do now. Select the object in a scene view. Then, choose local representation of rotations (the very right tool in the pic).
And look if the side you want see as a face side represents Z axis.
IF THE PREVIOUS PART DIDNT WORK:
I dont understand, the object are rotated at all or not? I just see that all objects in your screenshot are pointing down regardless their position relative to the centre. So, if you remove the line for a while where you set up the rotation for the object, then it will change anything?
i think i understand what you mean, i’ve basically been visually debugging this time using a Cone for telling which direction my cubes are facing, I would have a cone attached to a cube as a child, then I can understand where it thinks it’s facing is that makes sense.
I’m wondering if my problem could be a level higher, in each of the nodes/points I have a hexagon made of six cubes, where i’ve stated a rotation based on the amount of objects /180 * i, and then distributed positions in a circle to make the hexagon-ish shape.
I’m wondering if that’s overriding my attempts to rotate the parent with other script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Placer : MonoBehaviour {
public GameObject prefab;
public int numberOfObjects = 6;
public float radius = 0.37f;
private Transform self;
public Transform parent;
bool started = false;
private Vector3 center = new Vector3(0,0,0);
private GameObject go;
void Start()
{
if (started == false)
{
self = gameObject.transform;
float ang = 180 / numberOfObjects;
for (int i = 0; i < numberOfObjects; i++)
{
float angle = i * Mathf.PI * 2 / numberOfObjects;
Vector3 pos = new Vector3 (Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Vector3 posOffset = self.position + pos;
GameObject newThing = (GameObject)GameObject.Instantiate(prefab, posOffset, Quaternion.Euler(0, ang * i, 0));
newThing.transform.parent = parent.transform;
}
started = true;
}
}
}
The self pos is given by the points on a sphere made in another script that shouldn’t give any problems down the chain.
I’m just wondering if it could be solved in this script, but attempts to change parent rotation from here haven’t been successful.
Thanks for the help btw how did you attach the images so they appear in the forum?
Accidental coolness, not what I was after but looks interesting:
Vector Direction:
Cones and group facing:
individual from group facing:
So I think I know what needs to do be done, I’m not sure how to achieve it, too fatigued, I’ve got the group facing the right direction, except the group gets made with no awareness of the rotation facing or something
Thank you very much for your help, I think I’ve get it sorted, except I have one problem to overcome.
I have the parent facing towards the center of the sphere, however it’s not the axis I would like facing the center, I have the z axis blue arrow facing center, I need the green arrow Y axis to face the center, is there a way to flip this? I tried putting in an parent offset and flipping it there but that didn’t seem to work.
Still just using this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rotater2 : MonoBehaviour
{
bool hasStarted = false;
private Transform targetTransform;
// Update is called once per frame
void Update ()
{
if (hasStarted == false)
{
targetTransform = GameObject.Find("Cube").transform;
Vector3 relativePos = targetTransform.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(relativePos);
// Debug.Log ("pos" + transform.position);
// Debug.Log ("RelPosition" + relativePos);
// Debug.DrawRay(transform.position, relativePos, Color.red);
this.gameObject.transform.rotation = rotation;
hasStarted = true;
}
}
}