Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by chrismcrae5712 · Oct 09, 2014 at 10:20 PM · tutorial

In-Game Object Placement

Okay So I been looking all over the web for the past 2 days and have had zero luck. I find videos on what other people have created, but nothing on how they created it. What I am looking for a is a tutorial or even just some pointers or tips on how to create an in-game object placement script that allows the player to place the selected object in the game. However, I want them to only be able to place on a grid that they have to purchase (Ex: purchase a piece of property then place on the available grid spaces)

If anyone knows of a such tutorial please point me to it. Thanks.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ThePunisher · Oct 09, 2014 at 10:23 PM 0
Share

This seems more like a discussion in the unity forums ins$$anonymous$$d of UnityAnswers since it doesn't really have a concise solution.

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by DESTRUKTORR · Oct 09, 2014 at 10:54 PM

I will point you in the direction of the places in the unity script references that you should look, but I will not make these scripts for you, and I will not encourage the use of Unity Answers as an alternative to Google (see the tutorial video on how to use Unity Answers).

There are essentially two aspects you should consider before deciding how you want to create GameObjects and components, at runtime (i.e. after the scene has been loaded).

  1. How large/diverse is the set of potential objects to be placed in game?

  2. How complex are the individual objects?

Prefabs are by far the defacto standard for getting complex objects into a game, but they are not always appropriate.

If you have a plethora of simplistic, but diverse objects to choose from, you may want to consider simply creating new GameObjects and adding components to them, manually.

Keep in mind that no matter what, instantiating GameObjects and populating them with components (as well as instantiating prefabs) are relatively computationally expensive operations, and it is not suggested that you attempt to instantiate a large number of them during normal gameplay, as it can produce quite a bit of lag, not to mention the memory they would take up.

Essentially what you're trying to do (if you break it down into simpler steps) is to take the player, figure out where they are, and use that along with the rotation of the camera attached to them to figure out what they are looking at, and use that to approximate a grid position. This would be best done with a RayCast.

Averaging that down to a position on a grid is just a matter of deciding how big your grid spaces are, with respect to each axis, and doing a bit of algebra. The simplest version of this would likely just truncate the float position on each axis to an integer cough cast cough and call that the current space.

How you decide how to select an object is more up to you to decide. That could vary anywhere from some sort of GUI system to literally walking up to a specific object (in 3D space) and performing some manner of input (say, pressing a key or clicking a mouse button).

The GUI would be the "simplest" way, but the 3D space version would be essentially the opposite version of the placement part of the script, so it may actually be easier to program and design.

However, if you want more detailed answers, I would strongly suggest asking more detailed questions. Giving the ol' "pizza order" request, listing off a bunch of features you want your game/mechanic/script to have, then saying "point me to someone who will show me how to make that" or "make it for me" or anything along those lines is not going to illicit a great response from most of the users here who would know how to fulfill your request, because the purpose of this place is not to give people free code. There are plenty of other places for that sort of thing (such as the Unify Wiki) and it's certainly not to be used as a replacement for a simple Google search.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by AxisRob · Feb 16, 2015 at 04:47 AM

I really don't think that "Let me google that for you" I appropriate. I also don't like that there really is a lack of information on how do this professionally (i.e. create a preview of the object that's transparent before snapping in, etc).

I do, however, love that it links back to this thread as the first result.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by PuzzleBuilder · Apr 01 at 02:01 AM

If someone is looking for inspiration or ideas for how to accomplish in-game object placement, you might find this script helpful. It's designed for a FPS game, not RTS. It doesn't feature a grid, but I think you could tweak it to make it work for that. Note that the overlap sphere is hardcoded, and so it may not work for every situation. This should just be used as a starting place anyway, not a fully polished script to toss in a game. One could try to generalize this to walls and not just horizontal surfaces by using RaycastHit.normal.

 using UnityEngine;
 using UnityEngine.InputSystem;
 
 // place this on camera
 public class ObjectPlacer : MonoBehaviour
 {
     public GameObject ghostPrefab; // prefab displayed when finding placement
     public GameObject placementPrefab; // prefab instantiated
     public GameObject ghostParent; // parent of ghost (place 3 units in front of camera as child)
 
     public bool placingObject; // set to true to see ObjectPlacer working
 
     public Material ghostMaterialValid; // material set when placement is valid 
     public Material ghostMaterialInvalid;
 
     private MyCharacterInput characterInput; // new input system
 
     InputAction confirmAction; // confirm placement
     InputAction cancelAction; // cancel placement
 
     bool wasValidPosition = false;
     int floorLayer = 14; // layer that objects should be placed on
 
     MeshRenderer[] renderers;
     SkinnedMeshRenderer[] sRenderers;
     GameObject ghostInstance;
 
 
     // set up player input and instantiate ghost
     void Awake()
     {
         characterInput = new MyCharacterInput();
         if (placingObject)
         {
             startPlacing();
         }
     }
 
     private void OnEnable()
     {
         confirmAction = characterInput.Gameplay.Action;
         confirmAction.performed += performInteract;
         confirmAction.Enable();
 
         cancelAction = characterInput.Gameplay.ClosePanel;
         cancelAction.performed += stopPlacing;
         cancelAction.Enable();
     }
 
     // create ghost and set material
     public void startPlacing()
     {
         ghostInstance = GameObject.Instantiate(ghostPrefab, ghostParent.transform);
         renderers = ghostInstance.transform.GetComponentsInChildren<MeshRenderer>();
         sRenderers = ghostInstance.transform.GetComponentsInChildren<SkinnedMeshRenderer>();
         if (wasValidPosition)
         {
             setGhostMaterial(ghostMaterialValid);
         }
         else
         {
             setGhostMaterial(ghostMaterialInvalid);
         }
     }
 
     void setGhostMaterial(Material newMaterial)
     {
         for (int i = 0; i < renderers.Length; i++)
         {
             Material[] mats = new Material[renderers[i].materials.Length];
             for (int j = 0; j < mats.Length; j++)
             {
                 mats[j] = newMaterial;
             }
             renderers[i].materials = mats;
         }
 
         for (int i = 0; i < sRenderers.Length; i++)
         {
             Material[] mats = new Material[sRenderers[i].materials.Length];
             for (int j = 0; j < mats.Length; j++)
             {
                 mats[j] = newMaterial;
             }
             sRenderers[i].materials = mats;
         }
     }
 
     // call to end placement process
     public void stopPlacing(InputAction.CallbackContext obj)
     {
         placingObject = false;
         GameObject.Destroy(ghostInstance);
     }
 
     // called when player confirms placement via input
     private void performInteract(InputAction.CallbackContext obj)
     {
         if (wasValidPosition && placingObject)
         {
             // instantiate prefab where ghost was
             GameObject.Instantiate(placementPrefab, ghostInstance.transform.position, ghostInstance.transform.rotation);
         }
     }
 
     // core functionality is here
     void FixedUpdate()
     {
         if (placingObject)
         {
             int detectLayer = 1 << floorLayer; 
             RaycastHit hit;
             // check if ray hits floor
             if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, 3.0f, detectLayer))
             {
                 // move placement according to hit
                 ghostInstance.transform.position = hit.point;
                 ghostInstance.transform.rotation = Quaternion.identity;
 
                 // use overlap sphere to check if placement is invalid due to overlap with colliders
                 // sphere is positioned a little above the floor
                 Vector3 spherePosition = new Vector3(
                     ghostInstance.transform.position.x,
                     ghostInstance.transform.position.y + .6f,
                     ghostInstance.transform.position.z
                     );
                 Collider[] hitColliders = Physics.OverlapSphere(spherePosition, .3f);
                 bool validPlacement = true;
                 foreach (var hitCollider in hitColliders)
                 {
                     // if the name isn't one that we should ignore and it isn't a trigger
                     if (!(nameMatchesPrefab(hitCollider.name)) && !(hitCollider.GetComponent<Collider>().isTrigger))
                     {
                         validPlacement = false;
                         Debug.Log("collider overlap " + hitCollider.name);
                     }
                 }
                 // if placement is valid
                 if (validPlacement)
                 {
                     // if it wasn't previously a valid placement, it is now
                     if (!wasValidPosition)
                     {
                         setGhostMaterial(ghostMaterialValid);
                         wasValidPosition = true;
                     }
                     Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.blue);
                 }
                 else
                 {
                     Debug.Log("cannot place because of collider overlap ");
                     // if it was previously a valid placement, it isn't anymore
                     if (wasValidPosition)
                     {
                         setGhostMaterial(ghostMaterialInvalid);
                         wasValidPosition = false;
                     }
                     Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.magenta);
                 }
             }
             // else raycast didn't hit any floor layer colliders
             else
             {
                 // if it was previously a valid placement, it isn't anymore
                 if (wasValidPosition)
                 {
                     setGhostMaterial(ghostMaterialInvalid);
                     ghostInstance.transform.localPosition = Vector3.zero;
                     wasValidPosition = false;
                 }
                 Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 3.0f, Color.red);
             }
         }
 
         // does collider name match any colliders in prefab
         bool nameMatchesPrefab(string colliderName)
         {
             bool match = false;
             if (colliderName.StartsWith(ghostPrefab.name))
             {
                 match = true;
             }
             Collider[] colliders = ghostPrefab.GetComponentsInChildren<Collider>();
             for (int i = 0; i < colliders.Length; i++)
             {
                 if (colliderName == colliders[i].gameObject.name)
                 {
                     match = true;
                 }
             }
             
             return match;
         }
         
     }
     private void OnDisable()
     {
         confirmAction.Disable();
         cancelAction.Disable();
     }
 
 }
 

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

32 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

UnityPaint, some references? 1 Answer

Why does this happen to my capsule collider at runtime? 2 Answers

Survival Shooter Tutorial fix for Unity 5 3 Answers

Problem with a Unity tutorial 0 Answers

Unity UFO tutorial question about code 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges