- Home /
Bullet hole random rotation and size
Hi! I'm new to the Unity and I'm learning how to make a basic FPS. Right now, I'm stuck at making bullet holes have random rotation along the normal.
My code:
public float Cooldown = 0.1f;
float CooldownRemaining = 0;
public float Range = 100.0f;
public float BulletHoleOffset = 1.0f;
public GameObject debrisPrefab;
public GameObject BulletHole;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
CooldownRemaining -= Time.deltaTime;
if (Input.GetMouseButton(0) && CooldownRemaining <= 0)
{
CooldownRemaining = Cooldown;
Ray ray = new Ray(Camera.main.transform.position + Camera.main.transform.forward, Camera.main.transform.forward);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, Range))
{
Vector3 hitPoint = hit.point;
if (debrisPrefab != null)
{
//Particle effect
Instantiate(debrisPrefab, hitPoint, Quaternion.FromToRotation(Vector3.up, hit.normal));
//Bullet Hole
Instantiate(BulletHole, hitPoint + (hit.normal * BulletHoleOffset), Quaternion.FromToRotation(Vector3.forward, hit.normal));
}
}
}
}
I'm stuck at "Quaternion.FromToRotation(Vector3.forward, hit.normal));" since I don't know where to "plug" random rotation along the normal. I managed to get a random rotation along particular axis, but it didn't look good since it didn't align with the normal.
Similar to above. How to achive random hole size?
Thanks in advance!
Answer by Cherno · Sep 28, 2015 at 10:42 AM
Use Transform.Rotate, note that oyu can pass a parameter that tells the method to use local space (which is always the default value if you don't pass the parameter). Rotate random degrees around the local y-axis and you are set :) For the random scale, just pass a Vector3 composed of random values to the bullet Transform's localScale variable.
//Bullet Hole
GameObject bulletHole = Instantiate(BulletHole, hitPoint + (hit.normal * BulletHoleOffset), Quaternion.FromToRotation(Vector3.forward, hit.normal));
float randomRot = Random.Range(0f, 360f);
bulletHole.transform.Rotate(bulletHole.transform.right * randomRot);
float randomScale = Random.Range(0.5f, 1.5f);
bulletHole.transform.localScale = new Vector3(randomScale ,randomScale ,randomScale);
EDIT: CORRECTED CODE & SOLUTION (See comments below);
public float Cooldown = 0.1f;
float CooldownRemaining = 0;
public float Range = 100.0f;
public float BulletHoleOffset = 1.0f;
public GameObject debrisPrefab;
public GameObject BulletHole;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
CooldownRemaining -= Time.deltaTime;
if (Input.GetMouseButton(0) && CooldownRemaining <= 0)
{
CooldownRemaining = Cooldown;
Ray ray = new Ray(Camera.main.transform.position + Camera.main.transform.forward, Camera.main.transform.forward);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, Range))
{
Vector3 hitPoint = hit.point;
if (debrisPrefab != null)
{
//Particle effect
Instantiate(debrisPrefab, hitPoint, Quaternion.FromToRotation(Vector3.up, hit.normal));
//Bullet Hole
GameObject bulletHole = Instantiate(BulletHole, hitPoint + (hit.normal * BulletHoleOffset), Quaternion.identity) as GameObject;
bulletHole.transform.rotation = Quaternion.FromToRotation(bulletHole.transform.up, hit.normal) * bulletHole.transform.rotation;
float randomRot = Random.Range(0f, 360f);
bulletHole.transform.Rotate(0, randomRot, 0);
float randomScale = Random.Range(0.5f, 1.5f);
bulletHole.transform.localScale = new Vector3(randomScale ,randomScale ,randomScale);
}
}
}
}
I really appreciate your help! I've managet to get random scale, which is good. Unfortunately, rotation doesn't seem to work. This is my code now:
GameObject bulletHole = Instantiate(BulletHole, hitPoint + (hit.normal * BulletHoleOffset), Quaternion.FromToRotation(Vector3.forward, hit.normal)) as GameObject;
float randomRot = Random.Range(0f, 360f); bulletHole.transform.Rotate(bulletHole.transform.right * randomRot); float randomScale = Random.Range(0.1f, 0.2f); bulletHole.transform.localScale = new Vector3(randomScale, randomScale, randomScale);
I've tried adding "...transform.right * randomRot, "Space.Self"), but saw no changes.
This is how it looks like: http://puu.sh/kruIv/6a1db77791.jpg
Ok, I thought you had the normal aligment already covered.
Note that you use the following code for the alignment:
Quaternion.FromToRotation(Vector3.forward, hit.normal));
You use Vector3, which always means world space (Vector3.forward = positive z on the z axis). You want to use local space:
Quaternion.FromToRotation(bulletHole.transform.forward, hit.normal));
In the end, the axis you have to use depends on the bulletHole's pivot orientation, so experiement a bit and use bulletHole.transform.up if forward is the wrong axis (or even bulletHole.transform.right).
The same goes for the random rotation; experiemtn with different axes:
bulletHole.transform.Rotate(bulletHole.transform.up * randomRot);
or
bulletHole.transform.Rotate(bulletHole.transform.forward * randomRot);
Ugh, somehow I managed to delete the comment. -_-
Unfortunately, it still doesn't work. I tried transform.up, forward and right. No dice. It just changes the rotation of the hole, but it's not aligned with the normal at all. This is what I get: http://puu.sh/ksueQ/34985c94b3.jpg On the bright side, they seem to face tghe same local axis. When I use Vector3, holes are aligned with normal, but then random rotation doesn't work. Also, on which axis does "bulletHole.transform.Rotate(bulletHole.transform.forward*randomRot)" rotate the object?
I have to ask, the original bullethole prefab (which is located in prefab folder) is zeroed out and is rotated 90 degrees on the x axis. When I run the game mode, shoot boxes a few tome, get back to edit mode, I see that original prefab (in the folder) now has random x,y,z position and rotation. Is that normal?
Unfortunately, it still doesn't work. This is what I get: http://puu.sh/ksueQ/34985c94b3.jpg No matter if I use transform.up, forward or right. It just rotates in a different way, but is never aligned with normal. On the bright side, they seem to face same local axis on any normal.
I also couldn't use "Quaternion.FromToRotation(bulletHole.transform.forward, hit.normal));" I had to use "BulletHole". I even tried rena$$anonymous$$g everything to "bulletHole" everywhere. Same thing happens. Only time I get holes to appear exactly on normal is when I use Vector3.
I also have to ask, my default prefab (located in "prefab" folder) is zeroed out and rotated 90 degrees on the x axis. But if I run the game, shoot the boxes, go back to editing, the original prefab (in the folder) now has random x,y and z rotation and position. Is this normal?
Be very careful now. Look at how you named you variables.
The variable that holds a reference to your prefab is called "BulletHole". This is ONLY USED ONCE: You pass it to the Instantiate function. the temporary "bulletHole" variable is the variable that holds the clone that is instantiated, and this is also the gameobject (or rather, it's transform) for all the bulletHole.transform.up etc. rotation and whatnot operations.
To make myself even more clear:
public float Cooldown = 0.1f;
float CooldownRemaining = 0;
public float Range = 100.0f;
public float BulletHoleOffset = 1.0f;
public GameObject debrisPrefab;
public GameObject BulletHole;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
CooldownRemaining -= Time.deltaTime;
if (Input.Get$$anonymous$$ouseButton(0) && CooldownRemaining <= 0)
{
CooldownRemaining = Cooldown;
Ray ray = new Ray(Camera.main.transform.position + Camera.main.transform.forward, Camera.main.transform.forward);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, Range))
{
Vector3 hitPoint = hit.point;
if (debrisPrefab != null)
{
//Particle effect
Instantiate(debrisPrefab, hitPoint, Quaternion.FromToRotation(Vector3.up, hit.normal));
//Bullet Hole
GameObject bulletHole = Instantiate(BulletHole, hitPoint + (hit.normal * BulletHoleOffset), Quaternion.identity) as GameObject;
bulletHole.transform.rotation = Quaternion.FromToRotation(bulletHole.transform.up, hit.normal) * bulletHole.transform.rotation;
float randomRot = Random.Range(0f, 360f);
bulletHole.transform.Rotate(bulletHole.transform.up * randomRot);
float randomScale = Random.Range(0.5f, 1.5f);
bulletHole.transform.localScale = new Vector3(randomScale ,randomScale ,randomScale);
}
}
}
}
I'm starting to believe it's not possible to achive. I literally copy-pasted your code and it gave me this error: http://puu.sh/ksDtL/79009a4686.png
So I added "...as GameObject;" at the end and the error went away.
But holes are still sticking out and not aligned to the normal.
I appreciate your help, but this is really nuts!
Your answer
Follow this Question
Related Questions
Reseting rotation of a random turret 1 Answer
java scrip, dice throw at a random rotation and force? 1 Answer
Gun Random Rotation 0 Answers
Object Rotating Randomly 1 Answer
Random Turning? 1 Answer