#no object with the proper layerMask to

1 messages · Page 1 of 1 (latest)

still gust
#

making a thread for this since it's gone on for a while

dusky reef
#

yeah smart

#

wait this run confuses me

still gust
#

If the phantom walls don't get highlighted when you click the log entry, then the game object is gone

dusky reef
#

the coords for that hit are on the blue circle

dusky reef
still gust
#

How do you add a wall to a room frame?

dusky reef
#
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Experimental.GraphView;
using UnityEngine;

/* Script Purpose
 *  Highlight where mouse is pointing with a red frame
 */
public class RedFrame : MonoBehaviour
{
    [SerializeField] GameObject outline;
    private GameObject currentFrame;
    [SerializeField] BoxCollider boxScale;//scales frame to match that of hitbox
    [SerializeField] private LayerMask theLayerMask;
    private void Update()
    {
        theLayerMask = AddCube.SetFinalMask(PlaceSelect.PlaceMode());
        Destroy(currentFrame);

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//where user hovers mouse over
        bool cast = Physics.Raycast(ray, out RaycastHit hit, 500f, theLayerMask);
        if (cast && hit.transform.gameObject.CompareTag("Room"))//if user hovers mouse over a room
        {
            Vector3 v = 90f * hit.normal;
            Vector3 normals = Quaternion.AngleAxis(90, Vector3.up) * v;//rotates object to face outwards
            currentFrame = Instantiate(outline, hit.transform.position + VectorMult(hit.normal, boxScale.size) * 0.5f, Quaternion.Euler(normals));//generates new outline
        }else if (cast && hit.transform.gameObject.CompareTag("FakeWall"))
        {
            currentFrame = Instantiate(outline, hit.transform.position, Quaternion.Euler(-90f, hit.transform.eulerAngles.y, hit.transform.eulerAngles.z));
        }
    }

    private Vector3 VectorMult(Vector3 firstVector, Vector3 secondVector)//outputs (x1*x2, y1*y2, z1*z2), basically a half dot product
    {
        return new Vector3(firstVector.x * secondVector.x, firstVector.y * secondVector.y, firstVector.z * secondVector.z);
        //blender objects have Z up, unity has Y up. Swapped the two. Unswap if for unity objects or importing meshes from a Y up software
    }
}```
#

this is the only destructive code

#

and it destroys the red frame that highlights where the mouse is pointing

#
    void WallSelect(RaycastHit hit, GameObject Wall)
    {
        GameObject newWall = Instantiate(Wall, hit.transform.position, Quaternion.Euler(new Vector3(0,hit.transform.eulerAngles.y,0)), hit.transform);
        /* NOTE: 
         * sometimes, this ray points down. I don't know why but it does not produce any issues yet. In the future, it might, so I have left this debug function in here for you
         * Debug.DrawRay(hit.transform.position, hit.transform.rotation * new Vector3(0, -1f, 0f), color:Color.green, 5f);
         * */
        if (Physics.Raycast(hit.transform.position, hit.transform.rotation * new Vector3(0, -1f, 0f), out RaycastHit hitInfo, 0.5f, wallMask))
        {
            Instantiate(newWall, hitInfo.transform.position, Quaternion.Euler(new Vector3(0, hitInfo.transform.eulerAngles.y, 0)), hitInfo.transform);
        }
    }```
#

this is the code to add a new wall

#
    void Update()
    {
        PlaceSelect.Mode mode = PlaceSelect.PlaceMode();
        finalMask = SetFinalMask(mode);

        if (Input.GetMouseButtonDown(0))//if user clicks
        {   //raycasts passing through blender objects for some reason
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//where user clicks
            bool cast = Physics.Raycast(ray, out RaycastHit hit, 500f, finalMask);
            
            if (cast && !hit.transform.gameObject.CompareTag("Untagged"))//if user clicks an object, make something
            {
                switch (mode)
                {
                    case PlaceSelect.Mode.Room:
                        RoomSelect(hit);
                        break;
                    case PlaceSelect.Mode.Wall:
                        KillChildren(hit.transform.gameObject);
                        WallSelect(hit, onlyWall);
                        break;
                }
            }
        }
    }```
#

and the Update() method where it is called in

#

finalMask in this case is set to wallMask because you have to be in wall select mode to add a wall and entering that mode sets finalMask to wallMask

still gust
#

can you share the entire script in a single pastebin?

#

that will make it easier to read

dusky reef
#

oh sure

still gust
#

btw, Vector3.Scale already exists; you don't need vectorMult

dusky reef
#

I realized that

#

this is one of the older scripts I have written but has been recently modified with WallSelect

#

also vectorMult swaps y and z becauase blender models

still gust
#
void OnDestroy() {
  Debug.Log("Destroying: " + gameObject.GetInstanceID());
}
#

and also log hit.transform.gameObject.GetInstanceID() when you hit something in the FindNeighbors method

dusky reef
#

like where do I call that function

still gust
#

it's a message, like Update

#

put it on any component that's on the same object as the wall's collider

dusky reef
#

oh the function is autocalled

#

do I have to put it into a script I have or into WallEZ

still gust
#

i don't know what you mean by "into WallEZ"

#

put it into the script for any component that's attached to the same game object as the wall's collider

#

if no such component exists, make one

dusky reef
#

so just add this script as a component to WallEZHolder?

still gust
#

Add it to whatever object has the collider

#

also, I noticed that you instantiate Wall to get newWall, then instantiate newWall again

dusky reef
#

wait where?

still gust
#

WallSelect, lines 75 through 83

dusky reef
#

oh yeah

still gust
#

newWall is left parented to hit.transform

dusky reef
#

yeah that's a good point

still gust
#

the other wall is stuck onto whatever you hit in the raycast in that method

#

I don't really understand what's happening there

dusky reef
#

testing without newWall and changing 2nd instantiation to just Wall

#

for some reason no wall is generated

#

oh yeah

#

so basically, it adds a wall to where you click. Then, if it detects a room on the other side, it adds a wall

#

this ensures you don't have a one sided wall

#

so if I click here

#

nvm forgot to save

#

I should document that

still gust
#

I see

#

your life would be a fair bit easier if you fixed your rotations, by the way

dusky reef
#

yeah not commenting that was a crime

still gust
#

you can turn on "Apply Transforms" in Blender so that the model doesn't need any rotating in unity

dusky reef
#

and yeah I wrote that rotation code before I knew what Quaternion.AngleAxis was

still gust
#

(this causes problems if you have objects parented to each other in blender, though)

#

well, moreso, it seems weird that you'd be rotating a down-vector to get a vector that doesn't point down!

#

I presume your ray points down any time whatever you hit happens to not have that 90-degree X axis rotation you get by default

dusky reef
#

that;s why it points down

#

yeah in hindsight that should have been obvious

still gust
#

You know, one thing that comes to mind here

dusky reef
#

yeah?

still gust
#

RoomSelect calls KillChildren on the newly spawned room

#

oh hang on

#

yeah

#

GameObject newObj = Instantiate(hit.transform.gameObject, hit.transform.position + vectorMult(hit.normal, boxScale.size), hit.transform.rotation);

dusky reef
#

I MISSED THAT

still gust
#

You're cloning the room

#

The walls are destroyed, but destruction happens at the end of the frame.

dusky reef
#

so I make a room full of walls and then check if it has walls

#

yeah

still gust
#

The walls are still there.

#

So you hit them with your raycasts

#

Then the walls die at the end of the frame.

#

That's your issue.

dusky reef
#

so destroy the walls before cloning

#

fixes it

still gust
#

well, you do

#

well, you do it after calling Instantiate

#

then, in Start, the room does the raycasts

#

actually, that should be on the next frame...

dusky reef
#

yeah delay it a frame

#

because all destruction is at the end of the frame

#

a detail I forgot when writing that code

still gust
#

but i'd expect Start to have already done that for you

#

You can try making KillChildren deactivate the objects too

#

I need to scram in a few minutes btw

dusky reef
#

same lol

still gust
#

but that's my best hunch right now

dusky reef
#

yeah that makes perfect sense

#

how do I delay a function call until next frame?

still gust
#

It just doesn't square up with the raycasts happening in Start on the next frame

#

Start already doesn't run until the start of the next frame

dusky reef
#

so neither does KillChildren

#

because it is called in start

#

so I need to do it the frame after start is called

still gust
#

no, it's called over in RoomSelect

#

that's where I'm looking

dusky reef
#

oh yeah mb

still gust
#

Ah, but you're looking at its usage with WallSelect

#

anyway, try deactivating the objects and then destroying them

#

newObj.transform.GetChild(i).gameObject.SetActive(false);

dusky reef
#

it worked!

still gust
#

I'd have to squint at this harder to see why it worked. It feels like it shouldn't have

dusky reef
#

seriously thank you so much

still gust
#

but you're welcome anyway (:

dusky reef
#

Imma just blackbox it for now

still gust
#

I've gotten bitten by delayed destruction a few times

dusky reef
#

this bug has been beating me up for months

still gust
#

like repeatedly destroying the 0th child of a transform

#

(this goes on forever)

dusky reef
#

lol

#

I'm going to make deactivating before destroying my always practice from now on, thats seriously very helpful

#

alright though I'mma hop off for dinner now tysm!