Target is marked as a tEngineNode, not a tVehicle, so when you pass vehicle to target, it gets downcasted to a tEngineNode. So, before you can get speed, you have to cast it as a tVehicle.
However, this is a rather inconvenient way to get something. After all, you don't want to cast and check each time.
My personal preference is to use messaging.
E.g.,
All Objects have a default SendMessage method that you can override (not overload), it's under Language Reference->Objects in the documentation. The above example uses a custom method in the base class to return a float instead of an object.
player:tplayer=New tplayer vehicle:tvehicle=New tvehicle player.target=vehicle vehicle = Null ' Just to ingrain the fact that we are not using the old reference vehicle = tVehicle( player.target ) If vehicle Then Notify vehicle.speed
However, this is a rather inconvenient way to get something. After all, you don't want to cast and check each time.
My personal preference is to use messaging.
E.g.,
Const MSG_SPEED% = $00000001 Type tEngineNode Method SendMessageF:Float( msg:Int ) Return 0 End Method Field target:tenginenode EndType Type tPlayer Extends tEngineNode EndType Type tVehicle Extends tEngineNode Field speed#=100 Method SendMessageF:Float( msg:Int ) Select msg Case MSG_SPEED Return speed End Select Return 0 End Method EndType player:tplayer=New tplayer vehicle:tvehicle=New tvehicle player.target=vehicle Notify player.target.SendMessageF( MSG_SPEED )
All Objects have a default SendMessage method that you can override (not overload), it's under Language Reference->Objects in the documentation. The above example uses a custom method in the base class to return a float instead of an object.