• 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
Question by gernomino · May 15, 2022 at 03:20 PM · editor-scriptingeditorguieditorguilayouteditor extensionterrain-editor

OnSceneGUI render projection onto object surface

Main question

I'm building a custom Terrain editor, and I can't determine how to get a projection of the 'brush' to flow over the terrain like the built-in Unity terrain editor.
At the moment of I'm using Handles.DrawLines, function to render a square, but this doesn't "hug" the terrain shape.
I looked through the scripting API, but didn't find anything else in Handles, EditorUtility, or EditorGUIUtility that might be useful. I could possibly create a game object in the editor that projects onto the terrain, but not sure if you can hide it, unless I can somehow create non-permanent objects in OnSceneGUI. I could maybe use some kind of Gizmo but that looked like it was just for static renderings around the gameobject when it's rendered / didn't look like there was an option for mouse movement.
Random side blurb
Does anyone know of a good resource for creating custom Unity Editor functionality? I've been struggling to find any kind of explanation for how to do anything beyond adding a custom property to the inspector window. This is one of the things holding me back from actually developing in Unity, because I haven't been able to learn methods to create custom tooling in order to remove repetitive tasks.
Example questions - Can I create instance variables in an Editor class? Is that safe? - The question I'm asking now about creating the projection

Comment

People who like this

0 Show 0
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

1 Reply

· Add your reply
  • Sort: 
avatar image

Answer by Thygrrr · May 15, 2022 at 06:04 PM

Do you know the Normal Vector of the Terrain at the position you want to draw the brush? (probably, because you're creating the terrain yourself)

If the brush has a transform, you can just set transform.up to that normal. If not and your brush doesn't have to be square, you can use

 Handles.DrawSolidDisc(Vector3 center, Vector3 normal, float radius)

See - Unity Docs

radius can be your brush size, center is the position where the brush has touched the terrain (so its local height), and normal is the Terrain surface normal vector at that position.

Comment

People who like this

0 Show 3 · 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 gernomino · May 15, 2022 at 06:34 PM 0
Share

That's good point, I could do something with the normal as an in-between. I'd really like to have projection down onto the terrain like the built-in terrain editor does.

I tried DrawWireDisc, and it works fine, just doesn't project down onto the terrain. I'm using the square, so I didn't have to worry about the Texture2D.SetPixels algorithm to get the circle right.

I was actually wondering a bit ago if maybe the Unity Terrain uses its heightmap to create a mesh and then uses the DrawMesh from Gizmos. Didn't want to go far down into the rabbit hole before checking if there's another way.

avatar image Thygrrr gernomino · May 15, 2022 at 06:46 PM 0
Share

I see - that is probably done via a shader.

Perhaps you can get some mileage out of a Projector?

avatar image gernomino Thygrrr · Jun 09, 2022 at 11:20 PM 0
Share

I ended up looking back at using a Projector. That required me doing things a little differently. Instead of using DrawGizmos() within the Editor script, I created a full GameObject in OnEnable(), and gave it the Projector with appropriate settings. Then I reposition and toggle active state within OnSceneGUI(). I didn't think I was able to create GameObjects within the custom editor, but it seems to work fine. I created a custom Projector shader to add a sort of outline to the projection, but based it off of the shader in the Standard Assets.

Just wrote this code in case others come along and are curious. Not sure if it compiles properly because I just remade it.

 \
 [CustomEditor(typeof(MyThing))
 public class MyEditor : Editor
 {
   MyThing myThing;
   GameObject brush;
   Projector projector;
   Vector3 brushOffset = new Vector3(0, -1000, 0);
 
   void OnEnable()
   {
     myThing = (MyThing) target;
     brush = new GameObject();
     projector = brush.AddComponent<Projector>();
     // set projector settings like rotation
     projector.orthographicSize = 10;
   }
 
   void OnSceneGUI()
   {
     // Reposition brush
     brush.position = Event.current.mousePosition + brushOffset;
   }
 }


This is unrelated to my original question, but I also ended up using Graphics.Blit and a material to do the texture drawing. I used references from these unity docs for creating custom terrain tools and kind of reverse engineered it. https://docs.unity3d.com/Packages/com.unity.terrain-tools@4.0/manual/create-modify-terrain-heightmap.html

The one snag I hit was long render times. I was able to fix that by using AsyncGPUReadbackRequest, and inside of OnDisable() I check to make sure they're all finished. Removes a lot of lag I was getting when painting textures. https://docs.unity3d.com/ScriptReference/Rendering.AsyncGPUReadbackRequest.html

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

149 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 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 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 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 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

Custom inspector difficulties creating a Box / Group like widget 1 Answer

Better Unity Event UI 0 Answers

Retrieve default editor field / conditional hide field, 0 Answers

Track when the value is changed and get it 0 Answers

Custom Inspector for a List ? 2 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