tofanimation

  • 29 Apr
  • Joined 25 Apr
  • 0 best answers
  • DaveTheCoder Quotes are only needed when using a string literal, not when using a string variable.

    Aha, this did the trick! I removed the quotes and now the function finds the correct mesh in the node path. Here's what I ended up with:

    func _keymove(midi_event: InputEventMIDI): #make function point to the correct object based on midi_event.pitch
    	var key_node = str("KB/") + str(midi_event.pitch)
    	print (midi_event.pitch)
    	print (key_node)
    	print(get_node(key_node))
    	print(" ")
    	
    	if midi_event.message == 9:
    		get_node(key_node).rotation.x = deg*92.5
    	elif midi_event.message == 8:
    		get_node(key_node).rotation.x = deg*90

    Playing each note now prints an address to the console, something like 48:<Node3D#495870439857> for example, and of course moves the 3D mesh of the correct key.

    Thank you all for your ideas, each of which gave me a little insight into various aspects of how this works. I'm thankful to now have this as a handy part of my toolkit!

  • Tomcat
    Thanks Tomcat,
    this was helpful in understanding how to print quotes from a string:

    func _keymove(midi_event: InputEventMIDI): #make function point to the correct object based on midi_event.pitch
    	var key_node = '"' + str(midi_event.pitch) + '"'
    	print (midi_event.pitch)
    	print (key_node)
    	print (get_node(key_node))

    which prints:

    57
    "57"
    <Object#null>

    The quotes print, but unfortunately doesn't seem to be able to pass the node name on to get_node() successfully, as I still get the <Object#null> message. I'll keep playing with combinations of these suggestions for now...

  • Thanks for the ideas.
    I have been playing around with kuligs2's idea since it seemed a little more streamlined to what I am trying to do, but I still haven't cracked the code.

    First I tried the following:

    func _keymove(midi_event: InputEventMIDI):
    	var key_num = str(midi_event.pitch)
    	var key_node = get_parent().get_node(key_num)
    	if midi_event.message == 9:
    		key_node.rotation.x = deg*92.5
    	elif midi_event.message == 8:
    		key_node.rotation.x = deg*90

    When I press a note, the debug fails and I get the following error message:

    Invalid access to property or key 'rotation' on a base object of type 'null instance'.

    I backed up a step and simply had it simply print my variables:

    func _keymove(midi_event: InputEventMIDI):
    	var key_num = str(midi_event.pitch)
    	var key_node = get_node(key_num)
    	print (midi_event.pitch)
    	print (key_num)
    	print (key_node)

    The debug console prints the following when note 50 is pressed:

    50
    50
    <Object#null>

    "print (midi_event.pitch)" prints the key number as expected.
    "print (key_num)" also prints the same number, which means I probably don't need to pass midi_event.pitch to another variable, but no harm done.
    "print (key_node)" prints <Object#null> which seems to be why I was getting that error message about 'null instance'.

    Looking at the documentation again, the examples on the get_node() page all ask for the node name in quotes. The examples they give are:

    get_node("Sword")
    get_node("Backpack/Dagger")
    get_node("../Swamp/Alligator")
    get_node("/root/MyGame")

    All in quotes. Which leads me back to thinking I'd have to be able to include quotes within the string variable, but I can't figure out any way to do that, as the second quote always closes the first one, so nested quotes doesn't seem to be possible

    • Hello everyone!
      What I'm trying to do is create a visualization of a piano that responds to midi input. So far so good, but I am trying to figure out how to use the value of midi_event.pitch (which is a number corresponding to which note was pressed) and use that to pick an object (the correct piano key mesh) and move that object accordingly. Here's what I have so far, pretty straightforward, my node tree contains a node3d, with a child called KB, which has (for now) just two mesh3d instances, named 48 and 50, which corresponds to a C and D note respectively.

      func _ready():
      	OS.open_midi_inputs()
      	print(OS.get_connected_midi_inputs())
      	print(" ")
      
      func _input(input_event):
      	if input_event is InputEventMIDI:
      		_keymove(input_event)
      	
      func _keymove(midi_event: InputEventMIDI):
      	print (str(midi_event.pitch))
      	if midi_event.message == 9:
      		$"KB/50".rotation.x = deg*92.5
      	elif midi_event.message == 8:
      		$"KB/50".rotation.x = deg*90

      Of course key #50 is the only one that moves, no matter which note is played, which is as expected.
      Now, I could include a condition on the if/elif statements to see whether it is the correct key, and this does move key #50 only when the correct note is pressed:

      func _keymove(midi_event: InputEventMIDI):
      	print (str(midi_event.pitch))
      	if midi_event.message == 9 && midi_event.pitch==50:
      		$"KB/50".rotation.x = deg*92.5
      	elif midi_event.message == 8:
      		$"KB/50".rotation.x = deg*90

      but obviously this is grossly inefficient, since I'd end up with an if/elif for every single key that can be pressed, and whether the signal is a "note on" or "note off" message. On an 88 key controller that would mean a few hundred lines of elif statements. That's like sending a postman with only one letter and having him knock at every single door in town asking if he's at the right address!

      I have also tried many things to include the value in a string within the node path (such as having the value sent to a string as well as inluding it directly) but it doesn't seem like that is possible.

      What I'd like to do is take the value of midi_event.pitch and use that to choose which key moves. Thanks for any advice =)

      • kuligs2 replied to this.
      • Quotes are only needed when using a string literal, not when using a string variable.

        # string literal
        my_function("hello")
        
        # string variable
        var s: String = "hello"
        my_function(s)
        
        func my_function(s: String) -> void:
            pass