0 votes

Apologies in advance, I'm brand new at this.

I have a scene (.tscn) that contains a Spatial with a child MeshInstance of a rock model.

In my main scene, I load the rock scene, and call .instance.

On the instance, I thought I could call a function in the scene script, but I get "Nonexistant function 'Initialize' in base 'Spatial'".

I'm sorry to say, I don't know why :).

(Quick background: trying to make a moving asteroid field. I put initial rotation code in the rock scene, thinking it would get called when instanced. Moved the code to an Initialize function, which I cannot call. Also have _process code that I would like to be called on each to rotate each rock, but it doesn't get called. I'd like some help with that too :) )

Entire rock scene script:

extends Spatial

var minRotationalVelocity = 0.0
var maxRotationalVelocity = 0.040


var RNG = RandomNumberGenerator.new()

var xRotationVelocity = 0

var yRotationVelocity = 0

#var zRotationVelocity = RNG.randf_range(minRotationalVelocity, maxRotationalVelocity)

# Called when the node enters the scene tree for the first time.
func _ready():
    pass

func Initialize():

    print("Initialize Called")
    print("I am a rock")

    RNG.randomize()

    xRotationVelocity = randomNegate(RNG.randf_range(minRotationalVelocity, maxRotationalVelocity))

    RNG.randomize()

    yRotationVelocity = randomNegate(RNG.randf_range(minRotationalVelocity, maxRotationalVelocity))


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):

    var b = Basis()
    var xaxis = b.x
    var yaxis = b.y
    var zaxis = b.z

    rotate(xaxis, xRotationVelocity)
    rotate(yaxis, yRotationVelocity)
    #rotate(zaxis, zRotationVelocity)

    orthonormalize()

func randomNegate(value):

    var doIt = RNG.randi_range(1, 2)
    print(doIt)

    if(doIt == 2):
        value = -value

    return value

And entire main scene script:

extends Spatial

var initialObjectCount = 1000
var maxObjectCount = 50000
var maxDistanceFromOrigin = 100.0

var objectCount = 1

func AddObjects():

    if (objectCount >= maxObjectCount):
        return

    var numberToAdd  = clamp(objectCount * 2, initialObjectCount, maxObjectCount)

    var objectScene = load("res://moss rock 05.tscn")

    if(objectScene):

        print("LOADED")

        for i in range(objectCount, numberToAdd):

            var newObject = objectScene.instance()

            newObject.Initialize()

            var t = newObject.transform

            t.origin = Vector3(randf() * maxDistanceFromOrigin, randf() * maxDistanceFromOrigin, randf() * maxDistanceFromOrigin) - Vector3(0.5 * maxDistanceFromOrigin, 0.5 * maxDistanceFromOrigin, 0.5 * maxDistanceFromOrigin)

            newObject.set_transform(t)

            add_child(newObject)

            newObject.set_process(true)

        objectCount = objectCount + numberToAdd



    else:
        print("Failed to load asteroid object scene")

# Called when the node enters the scene tree for the first time.
func _ready():
    randomize()
    AddObjects()

var mouse_sens = 0.3
var camera_anglev=0

func _input(event):         
    if event is InputEventMouseMotion:
        $Camera.rotate_y(deg2rad(-event.relative.x*mouse_sens))
        var changev=-event.relative.y*mouse_sens
        if camera_anglev+changev>-50 and camera_anglev+changev<50:
            camera_anglev+=changev
            $Camera.rotate_x(deg2rad(changev))
in Engine by (46 points)

Look into using a 'singleton' to make functions global, that's going to be something handy for you to understand, probably in this context.

I think this might be helpful also: https://www.youtube.com/watch?v=iq4eOaox5Oo&t=7s

I'm relatively new to godot and I'm realizing it's important to create some fully functional super simple games and picking up the concepts along the way as you build more and more complex games.

1 Answer

+1 vote
Best answer

My only idea is that your "res://moss rock 05.tscn" scene doesn't have the script attached.

by (2,274 points)
selected by

Thanks for your answer. I'm so new, I don't know how to check for certain if it's attached to the scene - it sure looks like it is to me, but... If I just add a single instance of the rock scene to the main scene using the editor instead of code, that rock is oriented properly and rotates. Does that confirm the script is attached to the scene?
EDIT: It turns out I lied. I thought I was using the scene before, but I was using a MeshInstance - so adding the rock scene to the main scene in the editor does NOT give the correct behavior. I re-added a MeshInstance (and figured out how to attach the script), and that single one works. Still tinkering...

Okay - it turns out that was it! Thank you very much!

I think I had multiple confusions about what was happening when I did things in the editor.

I finally realized that the scene did not have the script attached (probably because it was created when the thing was a MeshInstance). I was able to drag and drop the .gd script file to the top level Spatial node in the rock scene, and voila! All my instances behaved as expected (after taking out Initialize, and restoring that code in the _ready function).

Thanks again!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.