Assign a Mesh to a Particle System using Script (Unity) - c#

so I have a custom mesh that I have generated using script and I want to assign it in a particle system but nothing will work. The first part of my code is where I delcare a public Mesh in my script just so I can assign the mesh there when I generate it and then take it from there to assign it to the particle system.
public Mesh Mesh;
[...]
Mesh = generated_mesh;
[...]
var shape = ps.shape;
shape.enabled = true;
shape.shapeType = ParticleSystemShapeType.MeshRenderer;
shape.mesh = Mesh;
The type changed to Mesh Renderer but the Mesh itself doesn't change.

Okay so it seems I was doing it the wrong way all along. I changed the shape type from mesh renderer to mesh and it's all good now. The confusing part is that when I was testing the particle system the only way I could assign the mesh to it manually was through the shape called mesh renderer and not the simple mesh. Anyway, it's all good now.
var shape = ps.shape;
shape.enabled = true;
shape.shapeType = ParticleSystemShapeType.Mesh;
shape.mesh = Mesh;

Related

Unity C# Adding Material Component to new GameObject

i have a problem about adding Material component to my new GameObject.
Situation: I have a big cube and a bullet. After bullet touches to the big cube. Big cube will be pieced 5x5x5. This is ok. I created small cubes for that. I wanna add to these cubes colors. I know that blabla.AddComponent();
blabla.GetComponent().xxx;
I used this method so as to add Rigidbody, but i couldn't add a Material.
My code:
piece.AddComponent();
piece.GetComponent().color = Color.red;
Can you say how can i add material ?
You can't, because Material is not a Component.
Rather, do the following:
var mr = GetComponent<MeshRenderer>();
mr.material = your material

How to match a box collider to a mesh with code in Unity?

My problem:
This is a generated triangle. I want to add more vertices later (4,5,6...). For the moment I want to add an collider2d for this meshes. Later I have pentagons and hexagons, this is the reason why I think that I need a BoxCollider2D.
After this:
BoxCollider2D boxCollider = gameObject.AddComponent<BoxCollider2D>();
I get the above result. When I add this:
MeshRenderer renderer = gameObject.GetComponent<MeshRenderer>();
boxCollider.offset = renderer.bounds.center;
boxCollider.size = renderer.bounds.size;
All my triangles are matched together:
And I get this error message in the added Box Collider2D:
I simply want to match the collider (green) to the mesh.
if your mesh is generated procedurally, your bounds might be incorrect. To fix this call
mesh.RecalculateBounds();

Positioning a gun at a constant place

I am trying to position my gun the way most fps games position it,
for example like this:
But I'm having a problem when I try to position and rotate it with the player. The gun doesn't rotate well and doesn't have the same position always.
Is there a way to keep a gun in the same position and make it rotate well with the player?
But my main problem is the position of the gun i need it to stay in one place like in every fps, when i start the game and pick a gun it spawn in diffrent location on the screen Because of the rotation.
Here's is the code that I am trying to use:
GameObject temp = GameObject.Find(gameObject.name);
playerGuns[keyPress] = Instantiate(temp, Player.transform.position
+ new Vector3(-2f, 3f, 4f), Quaternion.identity) as GameObject;
playerGuns[keyPress].name = gameObject.name;
playerGuns[keyPress].tag = gameObject.tag;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.rotation.SetLookRotation(Player.transform.position);
Alright here is the answer I promised:
First issue was with how you were setting your rotation, SetLookRotation takes in 2 parameters, Vector3 view, and Vector3 up the second is defaulted to Vector3.up. You were passing in the player.transform.position, for the "view" which is the direction you want transform to look in. Think of it like this, if I am far east facing west, my weapon will face east... (That is assuming the SetLookRotation normalizes it.) this is because my actual position is east, from some arbitrary origin. Something you could have used would have been player.transform.forward.
To spawn an object and have it have the same relative rotation and and position you can use Instantiate like you have in your original code. There are Several versions of instantiate.
In the comments I said to give yourself an offsetPosition and a eulerAngle, but this can be quite troublesome if you have multiple weapons. I mentioned I would give a recommendation for how I would set this up for multiple weapons... So here yea go.
Scriptable Objects,
In Unity you can create this objects to store information about a particular object, so for example a "Weapon" object can look like this:
using UnityEngine;
using System.Collections;
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapon")]
public class WeaponObject : ScriptableObject {
public string objectName = "New Weapon";
public Vector3 offSetPosition;
public Vector3 startOffsetRotation;
public float fireRate;
// Using a gameObject to store the weapon model so you can technical
// store the firing point.
public GameObject weaponModel;
}
You can create a new object now by right-clicking in your asset directory and going to create->weapon. Once you have done this you can rename the object it made, and the inspector will show all the public fields for this object you can modify.
With this you can create multiple weapons, and store their data in like a WeaponManager, that spawns every weapon. with something like:
WeaponObject weapon = WeaponManager.getWeapon(keyPress);
playerGuns[keyPress] = Instantiate(weapon.weaponModel, Player.transform.position + weapon.offsetPosition, Quaternion.identity) as GameObject;
playerGuns[keyPress].name = weapon.objectName;
playerGuns[keyPress].transform.parent = Player.transform;
playerGuns[keyPress].transform.eulerAngles = weapon.startOffsetRotation;
if(player.weaponScript != null) {
// we can have a single script for all of our weapons, and the WeaponObject
// will control its firerate, which projectiles it fires, etc.
player.weaponScript.setWeapon(weapon);
}
playerGuns[keyPress].transform.parent = Player.transform;
This line might be causing a problem. If you are parenting your gun to the players transform then it will follow the player. But it sounds like you want it to follow the camera?
try:
playerGuns[keyPress].transform.parent = Camera.main.transform;
Here is a useful answer provided by reddit user Mathias9807:
Many games will clear the depth buffer before drawing the gun model.
This will prevent the gun model from clipping through geometry but it
can look a bit weird when standing near a wall:
If you just want to render an object sticking to the camera you should
just get rid of the view matrix (Assuming you're using model-, view-
and projection matrices).
Explanation: Normally when you are using a view matrix (the camera matrix),the objects in the scene are being translated relative to the magnitude of the cameras position vector, and rotating by its yaw and pitch, which gives the illusion of a camera moving in a 3D space, but really there is no camera, just the objects in the scene that scale, and translate in in relation to the values defined for the camera.
So, when you remove that camera matrix for an object, the cameras position now has no influence on the models position, or put another way, the model does not move relative to the camera anymore but moves congruently with the camera.

Stop Mesh rendering if it intersect

I am generating a camera frustum mesh through code and it is working fine.
Now I am searching for a solution (shader based or else) to restrict
the camera frustum mesh if it intersects with any object. As you can see in the image, my frustum is passing through the plane which is not correct.
How can I control it? I searched and tried to apply different kinds of shaders but nothing seems to work.
Get the frustum planes of the camera.
Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(Camera.main); //Or whatever camera you are using
For each GameObject in the scene, get its Renderer component's bounds if any.
Renderer renderer = GetComponent<Renderer>();
if (renderer != null)
{
//get renderer.bounds
}
Test if the renderers bounds intersect with any of the frustum planes.
bool canSee = GeometryUtility.TestPlanesAABB(frustumPlanes, renderer.bounds);
if (canSee)
{
//do something
}
This should be a pretty good approximation of whether your camera can "see" the mesh (i.e if the frustum intersects with any object)

Adding a MeshFilter mesh via script?

How do you add a MeshFilter component with a specific mesh, let's say a Capsule mesh (from Unity default library resources), via C#? I'm this far ...
GameObject obj = new GameObject("Player");
MeshFilter meshFilter = obj.AddComponent<MeshFilter>();
meshFilter.mesh =
Capsule and other primitive meshes are in the Unity default resources and I know how to assign it in the editor but how do I obtain one in C#? Obviously instantiaion isn't available since it's a library asset.
UPDATE:
I would have thought that this would work:
meshFilter.mesh = Resources.Load<Mesh>("Capsule");
But the mesh is still null afterwards in the editor component inspector.
I am not aware about a direct way how to would not know a direct way how to do it, but there is the "hacky" way:
MeshFilter meshfilter = gameObject.AddComponent<MeshFilter>();
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Capsule);
meshfilter.mesh = go.GetComponent<MeshFilter>().mesh;
meshfilter.gameObject.AddComponent<MeshRenderer>();
Destroy(go);
Does that help?
GameObject obj=GameObject.CreatePrimitive(PrimitiveType.Capsule);
obj.name="Player";

Categories

Resources