I'm making a game in Unity where you can chop down trees, I want to make it so that particles spawn where you hit the tree. At this point the particles spawn where the player is, this is because the script is on the player. But how can I spawn the particles in the right place? (Where I hit the tree) It's probably not even that hard to solve, but I can't figure it out. My current C# code is below.
public class ChopTree : MonoBehaviour
{
public int damage = 25;
public Camera FPSCamera;
public float hitRange = 2.5f;
private TreeScript Tree;
// Particles
public GameObject particles;
void Update()
{
Ray ray = FPSCamera.ScreenPointToRay(new Vector2(Screen.width / 2, Screen.height / 2));
RaycastHit hitInfo;
if(Input.GetKeyDown(KeyCode.Mouse0))
{
if(Physics.Raycast(ray, out hitInfo, hitRange))
{
// The tag must be set on an object like a tree
if(hitInfo.collider.tag == "Tree" && isEquipped == true)
{
Tree = hitInfo.collider.GetComponentInParent<TreeScript>();
StartCoroutine(DamageTree());
StartCoroutine(ParticleShow());
}
}
}
}
private IEnumerator DamageTree()
{
// After 0.3 seconds the tree will lose HP
yield return new WaitForSeconds(0.3f);
Tree.health -= damage;
}
private IEnumerator ParticleShow()
{
// After 0.3 second the particles show up
yield return new WaitForSeconds(0.3f);
Instantiate(particles, transform.position, transform.rotation);
}
}
CodePudding user response:
If you are chopping the tree by clicking to screen then, you could spawn it where "hit" object is but, if you try to instantiate particle in place of hit object it would be a tree's origin so, you could add tree's collider to the surface of the tree and make it different object (Also you can make it child). So this way is not very smooth but you could create particles on the surface of the tree by this way.
Also if you are chopping it with character then, you could add collider which have enable onTrigger to tree and when you triggered you spawn a particle at where triggered object is.
CodePudding user response:
Well instead of
Instantiate(particles, transform.position, transform.rotation);
make sure you use the hit tree positions like
Instantiate(particles, Tree.transform.position, transform.rotation);
Actually personally I would merge both Coroutines together and pass in the according tree:
private IEnumerator ChopTree()
{
// After 0.3 seconds the tree will lose HP
yield return new WaitForSeconds(0.3f);
Instantiate(particles, Tree.transform.position, transform.rotation);
Tree.health -= damage;
}
and then
void Update()
{
var ray = FPSCamera.ScreenPointToRay(new Vector2(Screen.width / 2, Screen.height / 2));
if(Input.GetKeyDown(KeyCode.Mouse0))
{
if(Physics.Raycast(ray, out var hitInfo, hitRange))
{
// The tag must be set on an object like a tree
if(hitInfo.collider.CompareTag("Tree") && isEquipped)
{
var tree = hitInfo.collider.GetComponentInParent<TreeScript>();
if(tree)
{
StartCoroutine(ChopTree(tree));
}
}
}
}
}