I've been making a manager for decals on walls that conforms to the face by normals and it mainly consists of a particle system that uses .emit to put out a single particle (in this case the decal) at the point and normal vector of a collision that can be passed to the method. It works beautifully in the editor without any problems from 1 particle to 1000 at any point, but as soon as I try to open up a build of the game the blood doesn't appear at all. I've tried switching shaders, double sided shaders, and all of the options I can think of in the inspector, but since the particles are emitted through code I don't really use any of the modules so all I can extensively check are renderer and main settings. I also tried putting the system directly in front of camera as a child, but no luck. I have included screenshots below of the system's settings and a picture of the decals working in the editor and code below.
I've been stumped for a while now by this and I would really appreciate to hear what you guys think can help me out. Thank you in advance!
blood
settings1
settings2
private ParticleSystem ps;
void Start()
{
ps = gameObject.GetComponent<ParticleSystem>();
}
public void SpawnBlood(Vector3 pos, Vector3 normals)
{
float x = normals.x * .01f;
float y = normals.y * .01f;
float z = normals.z * .01f;
// moving position away from wall
var emitParams = new ParticleSystem.EmitParams();
emitParams.position = pos + new Vector3(x, y, z);
emitParams.rotation3D = Quaternion.FromToRotation(Vector3.forward, normals).eulerAngles;
ps.Emit(emitParams, 1);
//Debug.Log(normals);
}
It was due to the variable .isStatic only working in editor.
Related
I want a sprite to always face the camera, except in the Z-Axis. My sprites keep tipping left or right when I move the camera, and I can't have that.
I have been googling this for hours. I've tried transform.LookAt or Quaternion.LookRotation and manually setting the z to 0, but for whatever reason the z keeps adjusting. I've seen and tried so many solutions that feel like they should work but just don't. If it matters, my sprite is a child of another object, but trying localRotation doesn't work either. Freezing rigidbody constraints also has no effect.
The most accurate I can get it is this:
public class Billboard : MonoBehaviour
{
GameObject cam;
float minDist;
// Start is called before the first frame update
void Start()
{
cam = GameObject.Find("Main Camera");
}
// Update is called once per frame
void LateUpdate()
{
//Scale
minDist = cam.GetComponent<CameraOrbit>().distanceMin;
transform.localScale = new Vector3(1f, 1f, 1f) * (cam.GetComponent<CameraOrbit>().distance - minDist) * 1.01f / 3;
//Direction
transform.LookAt(cam.transform.position);
Vector3 rot = transform.rotation.eulerAngles;
transform.rotation = Quaternion.Euler(rot.x, rot.y, 0);
}
}
With this I can get the sprite to face the camera, but the z axis refuses to stay at zero.
Special thanks to StarManta for answering this question on the Unity Forums.
"OK, I think I see what's happening. Them looking like they're rotated is, I think, an illusion; I think they really are accurately pointing at the camera and right-side-up. But, you're treating the camera as if it has a round/fisheye projection, when it really has a rectilinear projection. Usually this doesn't matter but in this case it does. It's hard to explain exactly how this affects this, but the upshot is that, when things that are on either side of the center of the screen are set to "look towards" the camera, they actually appear to be rotated around their Y axes.
The solution to this is actually annoyingly simple: don't set the rotation to look at the camera, set it to be the same as the camera."
transform.rotation = cam.transform.rotation;
Have you tried rotation constraints?
https://docs.unity3d.com/Manual/class-RotationConstraint.html
I had a similar problem, where I wanted some 3d text to always look up, but rotated to the camera.
What worked for me was setting the undesired euler components to zero after applying the lookat rotation.
In your case, it would be something like this.
transform.LookAt(cam.transform.position);
var rot = transform.rotation.eulerAngles;
transform.rotation = Quaternion.Euler(rot.x, rot.y, 0);
In case you need another z value, just replace the 0.
Visual aid here
Please see visual aid. Following the gif, there are two GUIs. The GUI on the left is scaling properly based on the cameras distance to the object. The GUI on the right is scaling, seen clearly in the 'Scene' view, but not even noticeable in game view. The application is for the Hololens as the users head controls the camera within the Unity scene.
The problem lies in setting the objects scaling. Been racking my brain all day trying to replicate the type of scaling shown on the left GUI. Dividing the distance and using this as the factor to scale by is clearly incorrect as the object is either far too large and grows too fast, or far too small and grows too slowly but I don't know how to meet somewhere in the middle. Scaling in both directions equally at a noticeable yet not obnoxiously large or imperceptible rate.
Implementation code thus far:
// GameObject and GUI assigned in Editor
public GameObject sphere, rotationManager;
// For rotationManager scaling
private float cameraToObject,
void Update()
{
/* Scale rotationManager based on Cameras distance to object */
cameraToObject = Vector3.Distance(
sphere.transform.position,
Camera.main.transform.position);
Debug.Log("distance: " + cameraToObject);
// If camera isn't too close to our object
if (cameraToObject > 4f)
{
// adjust scale
rotationManager.transform.localScale = new Vector3(
cameraToObject / 5,
cameraToObject / 5,
rotationManager.localScale.z);
// enable rotationManager
rotationManager.gameObject.SetActive(true);
}
// Camera is too close, turn off GUI
else
rotationManager.gameObject.SetActive(false);
}
Not really sure what you are doing wrong, as dividing distance by constant must give required effect. Anyway try this code:
using UnityEngine;
public class AutoSize : MonoBehaviour
{
public float FixedSize = .005f;
public Camera Camera;
void Update ()
{
var distance = (Camera.transform.position - transform.position).magnitude;
var size = distance * FixedSize * Camera.fieldOfView;
transform.localScale = Vector3.one * size;
transform.forward = transform.position - Camera.transform.position;
}
}
It seems to work fine - preview
Also maybe it will be more effective to create constant menu size and just position it by converting world space to the screen space.
I'm working on converting a simple project of mine into a VR game. Currently, it's just a motorcycle that will zoom forward, and the player can use A or D (or left and right) to steer the cycle.
Here's my code so far:
void Start () {
cycleSphere = GetComponent<Rigidbody>();
}
void Update () {
inputX = Input.GetAxis("Horizontal");
}
void FixedUpdate () {
if (currentSpeed < maxSpeed)
currentSpeed += acceleration;
if (currentSpeed > 0)
cycleSphere.transform.Rotate (0, inputX, 0);
cycleSphere.velocity += transform.forward * currentSpeed;
}
I've imported GoogleVR SDK v1.70.0 and added the prefab, which allows me to view the game on my phone in VR and even look around without touching the code.
I want to make it so that if the player tilts his head left or right, the cycle will turn in the respective direction. How do I do that? Do I use Input.Gyro?
I've done something similar to this before, I made Pacman in Virtual Reality where tilting your head would steer the player (As in, tilting your head to the left so that your ear touches your shoulder, would steer the player, and vice versa).
I did it using Input.acceleration
For example, you can do something as simple as this:
void Update()
{
transform.Rotate(0f, Input.acceleration.x * acceleratorSensitivity, 0f);
}
Basically, you take the X rotation of your device (which would be your head tilting), apply your sensitivity (higher sensitivity means faster turning), and rotate your transform accordingly! :-)
I also think this approach is better than using the gyroscope as not all devices contain a gyroscope, but the majority of devices contain accelerometers (which at its basic level, rotates the screen).
You can use the main camera's transform.eulerAngles like so:
private float angle;
Update() {
angle = transform.eulerAngles.z;
}
This gives you the number of degrees of tilt, where a low value means tilting to the left, and a high (~360) value means tilting to the right.
In my testing just now it seems to give values of up to +-10 depending on where you look, even without any rotation.
I have found a solution for this if I were to be using translation as a means of movement:
http://answers.unity3d.com/questions/1035804/how-do-you-make-an-omnidirectional-2d-character-co.html
however I cannot find a solution for how to do this with my movement being physics based.
I have in my chracters controller the ability to rotate the camera around the z axis:
public Transform target;
private float cameraRot = 3;
if (Input.GetKey("q"))
{
target.transform.Rotate(0, 0, cameraRot);
}
I then have a script on all sprites in the world I am creating that rotates to always face the camera:
public Transform target;
void Start () {
target = GameObject.Find("MainCamera").GetComponent<Transform>();
}
void Update () {
if (target != null)
this.transform.rotation = Camera.main.transform.rotation;
}
That all works fine. However when I have rotated the camera, and therefore the sprites. The rigidbody movements become all skewed as they are rotating in the "global" space and not the "local".
I have tried placing the facecamera script on the child objects only to leave the rigidbody alone but this has no effect.
I hope I made this clear enough and that someone can help.
thank you very much for your time, if I find a solution I will mark the answer as correct and if I fix this myself before an answer I will update with how I fixed it.
The solution was to use:
Rigidbody.AddRelativeForce(Vector2.down * speed);
in lieu of:
Rigidbody.AddForce(Vector2.down * speed);
that adds the force in the local axis not the global.
documentation is here:
https://docs.unity3d.com/ScriptReference/Rigidbody.AddRelativeForce.html
I'm using unity to develop my game. I've made a custom swipe gesture by calculating the startPosition and the end Position of the touch. I got the vector direction by subtracting the two positions and debugged it successfully.
But when it comes to applying force to my game object I'm not getting any success after trying a lot.
here's what I'm doing:
swipeDirection = new Vector3(endPos.x - startPos.x,0f, endPos.z - startPos.z);
swipeDirection.Normalize();
Debug.Log("The direction is "+ swipeDirection);
ball.rigidbody.AddForce(swipeDirection * 5);
where ball is just a GameObject. Whenever I run it on my iPhone, the game just gets stuck giving a EXC_BAD_ACCESS code after the first swipe.
So I just tested your code. And it works. This issue you may be having is that those number are pretty small most likely, and you need a LOT of force to move it noticeably. Try changing your 5 to a 1000 or something big so you can definitely see the change. Here is my code, just added to a ball with rigidbody.
void Start ()
{
Vector3 dir = new Vector3 (100f, 0f, 0f);
dir.Normalize ();
this.gameObject.rigidbody.AddForce (dir * 100);
}
almost identical. you just need to make the multiplier big enough to see.
good luck.