Placing an Object at mouse position on a Terrain
I am traying to place an object based on the mouse position, before setting the object final position, I want the player to be able to move the object around the map to choose a location.
I try using a Raycast, but it sends the object to the center of the terrain, instead of the exact position the ray is hitting.
Does ray cast detects exact position in a Terrain? or does it only detecs the transfrom of the object a a whole?
any ideas what am i doing wrong?
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
namespace UnityStandardAssets.Characters.FirstPerson
{
public class ObjectPlacer : MonoBehaviour
{
public GameObject smelterdummy;
private ActionBar actionBar;
private InventoryV2 inventoryV2;
private PlayerHP playerHP;
private Actions actions;
private AudioSource collectSound;
private GameObject smelterGO;
private RaycastHit hit;
private bool once = true;
// Use this for initialization
void Start()
{
collectSound = GameObject.FindGameObjectWithTag("TakeSound").GetComponent<AudioSource>();
actionBar = GameObject.FindGameObjectWithTag("ActionBar").GetComponent<ActionBar>();
inventoryV2 = GameObject.FindGameObjectWithTag("GUI").GetComponent<InventoryV2>();
playerHP = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerHP>();
actions = GameObject.FindGameObjectWithTag("AM").GetComponent<Actions>();
}
// Update is called once per frame
void Update()
{
if (smelterGO != null)
{
Ray placefinder = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(placefinder, out hit, 300))
{
smelterGO.transform.position = hit.transform.position;
smelterGO.transform.position = new Vector3(smelterGO.transform.position.x, Terrain.activeTerrain.SampleHeight(smelterGO.transform.position), smelterGO.transform.position.z);
}
}
Placement();
}
public void OnMouseOver()
{
}
void Placement()
{
if (actionBar.actionBarSlot[actionBar.abPosition] == 23)
{
if (once)
{
once = false;
smelterGO = Instantiate(smelterdummy) as GameObject;
}
actions.disableOn = true;
}
else
{
Debug.Log("HEre!!");
actions.disableOn = false;
Destroy(smelterGO);
once = true;
}
}
}
}
Answer by Rostam24 · Sep 18, 2015 at 09:10 PM
You are right, if you get the position of the transform of the hit, you will get the pivot point of the transform. If you want the hit point, use raycasthit.point instead: http://docs.unity3d.com/ScriptReference/RaycastHit-point.html
You were absolutly right, but now my object is moving in clycles from the hit.point into the camera... over and over again... any ideas why? @Rostam24
Answer by raffaga · Sep 19, 2015 at 05:26 AM
In case someone is having a similar issue... I have a few empty objects with large colliders to limit spawn resorces in certain areas of my map. My object was doing that movement because the RayCast was colliding with this huge colliders. I added a Layer mask to my ray, so it would ignore everything but the terrain. it worked like a charm! Thanks ;)))
Answer by GXMark · Jan 24, 2017 at 02:45 PM
If you want to spawn an object on the terrain at some spawn distance in front of the camera only taking into account the camera y angle. Then you could write this.
float _spawnDistance = 30f;
float _terrainYOffset = 300f
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere)
// Calculate the spawn position
Vector3 spawnPosition = Camera.main.transform.position + Quaternion.AngleAxis(Camera.main.transform.eulerAngles.y, Vector3.up) * Vector3.forward * _spawnDistance;
// Add an offset to y to cater for terrain slope and object heights
spawnPosition = new Vector3(spawnPosition.x, spawnPosition.y + _terrainYOffset, spawnPosition.z);
// Raycast downwards to find terrain
RaycastHit hitPoint = new RaycastHit();
Physics.Linecast(spawnPosition, new Vector3(spawnPosition.x, spawnPosition.y - 1000, spawnPosition.z), out hitPoint);
// Place the object in front of camera
obj.transform.position = hitPoint.point + new Vector3(obj.transform.position.x, obj.transform.position.y + (obj.transform.localScale.y * 0.5f), obj.transform.position.z);
// If you want the spawned object to face the camera angle obj.transform.eulerAngles = new Vector3(0f, Camera.main.transform.eulerAngles.y, 0f);