#Fancy Fuel Tanks DEVBLOG
1 messages · Page 4 of 1
oh
i see
i just moved it vertically up
so what it does is generate the node, it doesnt place the node
im dumb LOL
hence "auto generate"
Okay, maybe a better term on my end would make users realize it doesnt do true magic just yet
now how to make sure it points the right direction
Just rotate it
clever
Like the rotation field flip one of them to 180
this is super easy
i like it
i just got used to having to type it all in that now that i can just auto generate, then move them manually is throwing my brain off lol
also i really hope the dev's are asking you, lux, munix and others how the mod manager should work and what we need lol
using KSP.Modules;
using KSP.Sim.Definitions;
using KSP.Sim.ResourceSystem;
using UnityEngine;
using KSP.Animation;
using KSP.Game;
public class TriggerController : MonoBehaviour
{
private Module_ResourceCapacities moduleResourceCapacities;
private TriggerVFXFromAnimation triggerVFX;
private ResourceDefinitionID fuelResourceId;
private void Start()
{
// Assuming the Module_ResourceCapacities is attached to the same game object.
moduleResourceCapacities = GetComponent<Module_ResourceCapacities>();
// Assuming the TriggerVFXFromAnimation is attached to the same game object.
triggerVFX = GetComponent<TriggerVFXFromAnimation>();
// Obtain the fuel ResourceDefinitionID from the ResourceDefinitionDatabase using the name of the resource
ResourceDefinitionDatabase definitionDatabase = GameManager.Instance.Game.ResourceDefinitionDatabase;
ResourceDefinitionData fuelDefinitionData = definitionDatabase.GetDefinitionDataByName("Fuel"); // Replace "Fuel" with the actual name of your fuel resource.
fuelResourceId = fuelDefinitionData.ID;
}
private void Update()
{
IResourceContainer fuelContainer = moduleResourceCapacities.OABPart.Containers[0];
float fuelLevel = (float)fuelContainer.GetResourceStoredUnits(fuelResourceId);
if (fuelLevel > 0.8)
{
triggerVFX.VFX01_ON();
}
else
{
triggerVFX.VFX01_OFF();
}
}
}
Not sure if this is the best way to go about checking fuel and turning off the animation but it seems the simplest way to do it
instead of calculating dV and everything it just tracks the fuel level until the fuel is at 0.8 then turns the animation off
nailed it. @dreamy escarp @lunar peak
IF anyone is wanting to get the fuel level for a fuel thank heres a script that works. Replace "fuel" with Methalox or whatever fuel type you're using. There's more that goes into getting the script to work as youll need certain modules and scripts added to your part in unity. It's also very early so whether it works 100% is untested. But its a solid start imo
using KSP.Modules;
using KSP.Sim.Definitions;
using KSP.Sim.ResourceSystem;
using UnityEngine;
using KSP.Animation;
using KSP.Game;
public class TriggerController : MonoBehaviour
{
private Module_ResourceCapacities moduleResourceCapacities;
private TriggerVFXFromAnimation triggerVFX;
private ResourceDefinitionID fuelResourceId;
private void Start()
{
moduleResourceCapacities = GetComponent<Module_ResourceCapacities>();
triggerVFX = GetComponent<TriggerVFXFromAnimation>();
ResourceDefinitionDatabase definitionDatabase = GameManager.Instance.Game.ResourceDefinitionDatabase;
fuelResourceId = definitionDatabase.GetResourceIDFromName("Fuel"); // Replace "Fuel" with the actual name of your fuel resource.
}
private void Update()
{
IResourceContainer fuelContainer = moduleResourceCapacities.OABPart.Containers[0];
float fuelLevel = (float)fuelContainer.GetResourceStoredUnits(fuelResourceId);
if (fuelLevel > 0.8)
{
triggerVFX.VFX01_ON();
}
else
{
triggerVFX.VFX01_OFF();
}
}
}
Nice work! This sort of thing will be very useful for parts mods!
It works too. I've gotta tweak settings in unity to make it function better but the script is good to go
This controls triggering an animation on and then off using a value. Which is very convenient imo
And obviously within the script you can see how to get the value of a fuel tank easily
This is what I like best about it - it's clear, concise, and easy to adapt. You've put an adjustable crescent wrench into the parts modding toolbox, not a specialized single purpose tool.
all the modules/scripts I added to the part. obviously youll need to make your own VFX and add a particle system to it.
with some tweaking with the Renderer in the particle system
so more work and fidgetting to do to make it work properly
aka learning how to use the anitmator/animation in unity
[LOG 09:18:40.767] Toggle: BTN-Stability-Assist changed to: True - CurActive: BTN-Stability-Assist
[WRN 09:18:40.792] IVA Portrait list was unable to generate portrait pages
[WRN 09:18:40.793] IVA Portraits couldn't be updated, no pages available to show
[WRN 09:18:40.818] The referenced script (KSP2UT.KSP2UnityTools.AttachmentNode) on this Behaviour is missing!
[WRN 09:18:40.818] The referenced script (KSP2UT.KSP2UnityTools.AttachmentNode) on this Behaviour is missing!
[WRN 09:18:40.818] The referenced script (KSP2UT.KSP2UnityTools.AttachmentNode) on this Behaviour is missing!
[WRN 09:18:40.819] The referenced script on this Behaviour (Game Object 'srfAttach') is missing!
[WRN 09:18:40.819] The referenced script on this Behaviour (Game Object 'srfAttach') is missing!
[WRN 09:18:40.819] The referenced script on this Behaviour (Game Object 'bottom') is missing!
[WRN 09:18:40.820] The referenced script on this Behaviour (Game Object 'bottom') is missing!
[WRN 09:18:40.820] The referenced script on this Behaviour (Game Object 'top') is missing!```
@upper summit for reference. no rush on this. just showing you and when you get a chance, if you know a fix or why the log is saying this.
Its saying this, because the referenced script, does not exist at runtime
It shouldn't matter, does it still work?
yes it works just fine
i just wasn't sure what it meant so wanted to show it to you
Its expected
Unfortunately idk how to strip the monobehaviours off of the go in the bundle
thats way above my paygrade lol
using KSP.Animation;
using KSP.Game;
using KSP.Modules;
using KSP.Sim.ResourceSystem;
using UnityEngine;
public class TriggerController : MonoBehaviour
{
private Module_ResourceCapacities moduleResourceCapacities;
private TriggerVFXFromAnimation triggerVFX;
private ResourceDefinitionID fuelResourceId;
private Animator animator;
private ParticleSystem particleSystem;
private void Start()
{
moduleResourceCapacities = GetComponent<Module_ResourceCapacities>();
triggerVFX = GetComponent<TriggerVFXFromAnimation>();
ResourceDefinitionDatabase definitionDatabase = GameManager.Instance.Game.ResourceDefinitionDatabase;
fuelResourceId = definitionDatabase.GetResourceIDFromName("Methalox"); // Replace "Fuel" with the actual name of your fuel resource.
animator = GetComponent<Animator>();
particleSystem = GetComponentInChildren<ParticleSystem>();
}
private void Update()
{
IResourceContainer fuelContainer = moduleResourceCapacities.OABPart.Containers[0];
float fuelLevel = (float)fuelContainer.GetResourceStoredUnits(fuelResourceId);
animator.SetFloat("FuelLevel", fuelLevel);
if (fuelLevel > 0.8)
{
triggerVFX.VFX01_ON();
if (particleSystem != null)
{
particleSystem.Play();
}
Debug.Log("VFX01_ON called");
animator.SetBool("IsFuelAbove80", true);
}
else
{
triggerVFX.VFX01_OFF();
if (particleSystem != null)
{
particleSystem.Stop();
}
Debug.Log("VFX01_OFF called");
animator.SetBool("IsFuelAbove80", false);
}
}
}
updated triggercontroller to utilize the particlesystem. without it it doesnt work properly
thats more for me
but if anyone is wanting to check fuel levels this script is dope
Ive exhausted my dark mana between yesterday and today and no amount of rum will bring that back like it did last night (/hj)
I mean look at this Cvusmo
Thats a PR i just made for SW
Every single c# file in sw, every single one was moved or changed in some way
i know why Jack!
cheese drank it all
spacewarp i glance at and go "that's a lot of work and ive no idea how that all works together but im happy because i dont have to worry about my mods breaking. or having to update them when they push an update"
That latter part is what was making me tear my hair out
Because I had to figure out type forwarding
even more simple:
using KSP.Game;
using KSP.Modules;
using KSP.Sim.ResourceSystem;
using UnityEngine;
public class TriggerController : MonoBehaviour
{
private Module_ResourceCapacities moduleResourceCapacities;
private TriggerVFXFromAnimation triggerVFX;
private ResourceDefinitionID fuelResourceId;
private Animator animator;
private void Start()
{
moduleResourceCapacities = GetComponent<Module_ResourceCapacities>();
triggerVFX = GetComponentInChildren<TriggerVFXFromAnimation>();
ResourceDefinitionDatabase definitionDatabase = GameManager.Instance.Game.ResourceDefinitionDatabase;
fuelResourceId = definitionDatabase.GetResourceIDFromName("Methalox"); // Replace "Fuel" with the actual name of your fuel resource.
animator = GetComponent<Animator>();
}
private void Update()
{
IResourceContainer fuelContainer = moduleResourceCapacities.OABPart.Containers[0];
float fuelLevel = (float)fuelContainer.GetResourceStoredUnits(fuelResourceId);
animator.SetFloat("FuelLevel", fuelLevel);
if (fuelLevel > 0.8)
{
Debug.Log("Fuel level above 80%");
}
else
{
Debug.Log("Fuel level below or equal to 80%");
}
}
}
So now all you have to do is create two animation clips, create an animation event for each. one is VFXON the other is VFX OFF.
This script is just a coordination script between the in-game scripts/modules and unity
If this is a monobehaviour
very simple and i think itll work?
Cant you just make the resource id a public field
Also, do you think I can release KSP2U2 v0.1.0 as is?
ah okay so heres what happens with the nodes
i think its almost ready but it needs a bit of tweaking with the attachment script
so i can manually move the nodes, but it doesnt apply the position and direction correctly to the parent gameobject
the workaround i did was to simply use the manual moving to quickly line up what i need, then enter the values manually into my prefab
so it works but i still had to enter those values because well it just creates the nodes for you.
so if thats how you designed it to be, then its good to go
How so?
ill record it real quick 1 sec
hm
video is too large to upload so heres screenshots of me moving the node in the gameobject top and then going to CV401 to show that the attach node top hasn't changed the position at all
Do you repress the button?
I really just need to rename to update attachment nodes
It's the auto that throws me off
Yeah, I feel like auto is giving too much magic to the system
Maybe "Select to Update Attach Node" or "Select to Generate Attach Node"
but its quite simple really
in the readme.md you can simply explain "move the node, go press the button again"
and it could be Generate Attach Nodes
or is it possible to do Generate Attach Nodes and then it changes to say "Re-Generate Attach Nodes"?
idk just thinking aloud
well thats awkward. it mae the z axis wild af
using KSP.Animation;
using KSP.Game;
using KSP.Modules;
using KSP.Sim.ResourceSystem;
using UnityEngine;
public class TriggerController : MonoBehaviour
{
private Module_ResourceCapacities moduleResourceCapacities;
private TriggerVFXFromAnimation triggerVFX;
private ResourceDefinitionID fuelResourceId;
private Animator animator;
private void Start()
{
moduleResourceCapacities = GetComponent<Module_ResourceCapacities>();
triggerVFX = GetComponentInChildren<TriggerVFXFromAnimation>();
ResourceDefinitionDatabase definitionDatabase = GameManager.Instance.Game.ResourceDefinitionDatabase;
fuelResourceId = definitionDatabase.GetResourceIDFromName("Methalox"); // Replace "Fuel" with the actual name of your fuel resource.
animator = GetComponent<Animator>();
}
private void Update()
{
IResourceContainer fuelContainer = moduleResourceCapacities.OABPart.Containers[0];
float fuelLevel = (float)fuelContainer.GetResourceStoredUnits(fuelResourceId);
animator.SetFloat("FuelLevel", fuelLevel);
}
}
@lunar peak it can be even simpler. You just have to setup Unity animations to do things. This script is basically the middle man between KSP2's TriggerVFXFromAnimation, the Animator Controller in Unity, and the Particle System in Unity
That is basically zero
Floating point error is a b*tch
basically just weird to see it produce that
i dont even wanna think about programming 3D vector coordinates
Remember: 0.1 + 0.2 ≠ 0.3
Its the same principle here
hm good point
Decimal numbers in computing are approximations
Information gets lost between computationd
What if someone wants a 45 degree attachment point
What do I round to, the nearest sqrt(2)/2?
round doesnt need to be to th neaerst int
can be lik 3 decimal places
tho i think that Mathf.Round is to the nearest in
probably Math.Round(float, 3)
Oh yeah that would work
@dreamy escarp how do i fix this? everything is named appropriately
you need to import the dll
1st add that script to your mod
and then generate the dll
and copy paste the dll onto unity
FFT.dll? Or assemblycsharp.dll thing?
fft
interesting, never thought aobut that bu tdoing it now
Be warned, it does require referencing a lot of assemblies (in unity), last I tried something like this
will this cause issues with the.DLL when I upload it as a zip?
you might need to re-add your components
Assets\FancyFuelTanks\Scripts\TriggerController.cs(2,7): error CS0246: The type or namespace name 'KSP' could not be found (are you missing a using directive or an assembly reference?)
Assets\FancyFuelTanks\Scripts\TriggerController.cs(3,7): error CS0246: The type or namespace name 'KSP' could not be found (are you missing a using directive or an assembly reference?)
Assets\FancyFuelTanks\Scripts\TriggerController.cs(4,7): error CS0246: The type or namespace name 'KSP' could not be found (are you missing a using directive or an assembly reference?)
what does read my components mean?
re add
i think you'll need to create an assmebly def
a sec
rename it, tick auto referenced and override references
and on the assembly references add the assembly-csharp
rename it to something else
doesnt really matter
The updated TriggerController. Now has 3 animations:
CoolingVFX_ON, CoolingVFX_OFF, CoolingVFX_LOOP
plus a lot of little checks
private void FixedUpdate()
{
IResourceContainer fuelContainer = _moduleResourceCapacities.OABPart.Containers[0];
float fuelLevel = (float)fuelContainer.GetResourceStoredUnits(_fuelResourceId);
_animator.SetFloat("FuelLevel", fuelLevel);
bool _isActive = _isActiveVessel.GetValueBool();
if (_isActive && !_wasActive)
{
if (fuelLevel > 0.8f)
{
_animator.Play("CoolingVFX_ON");
}
else
{
_animator.Play("CoolingVFX_LOOP");
}
_coolingVFXOFF = false;
}
else if (!_isActive && _wasActive && !_coolingVFXOFF)
{
if (fuelLevel < 0.8f)
{
_animator.Play("CoolingVFX_OFF");
_coolingVFXOFF = true;
}
}
_wasActive = _isActive;
}```
@lunar peak when you get a chance you mind taking a look and letting me know what you think
Not really sure what I'm looking for. What is _isActive? Is that a flag specific to your mod that you set on the vessel, or something else? Where is _wasActive initialized? Clearly _isActive is set before you use it, but not sure about _wasActive. So the first logic block you only go in if these two are true and false respectively, which means if you can go into the first block, then you certainly can't go into the second, however at the end of the first pass no matter what they were before they'll be ==, and thus after the first pass you're not gonna get into either block.
Where is _coolingVFXOFF initialized? That could get tested before it's been set if you're not initilizing it somewhere else first, though after you've gone through the first block it's sure to be set then and could allow you entry into the second block, except that any time you can get into the first block you're sure to not be able to get into the second...
How are you hoping / expecting this to play out in a normal use?
Your earlier post seems to show that _coolingVFXOFF is initialized here private bool _coolingVFXOFF = false;, so it's starting with a value that would permit entry into block 2
However that post seems to show that _wasActive is not initilized, which will be a problem the first pass through this code
_isActive is for the vessel to track if it's the active vessel the player is using.
_wasActive was to show that it's changed from the active vessel to something else
which could be just !_isActive
Ok, that helps a bit. I think maybe you would want to listen for the message that indicates the vessel has changed and just take an appropriate action when that happens.
that could be a simple way to do it
KSP.Messages.PropertyWatchers is the class that has IsActiveVessel
I'm a bit confused though. how is the mod supposed to work?
Does it run in the background just making things happen regardless of if a particular vessel is the active one or not?
Start: update methods are called then everything gets initialized. Logger from plugin is added
Enableemission: part of the particlesystem in unity and needed to turn on/off the particlesystem
disableemission: obvious
fixedupdate: gets the fuelContainer from _moduleResourceCapacities. Calculates fuellevel and seets it to the _animator
Is vessel active or not is checked and if it is it plays the CoolingVFX_ON
no
so in the plugin heres the fixedupdate fro the plugin
{
GameState? state = BaseSpaceWarpPlugin.Game?.GlobalGameState?.GetState();
if (state == GameState.Launchpad || state == GameState.FlightView || state == GameState.Runway)
{
GameObject controllableObject = GameObject.Find("CV401");
if (controllableObject != null && controllableObject.GetComponent<TriggerController>() == null)
{
TriggerController = controllableObject.AddComponent<TriggerController>();
}
if (TriggerController != null && _isActiveVessel.GetValueBool())
{
TriggerController.IsActive = true;
Logger.LogInfo("TriggerController IsActive = True");
}
}
else
{
if (TriggerController != null)
{
TriggerController.IsActive = false;
Logger.LogInfo("TriggerController IsActive = False");
}
}
}```
so it has to be in a certain gamestate for the triggercontroller to be activated, and then the triggercontroller does its own checks to make sure it's supposed to play the animations
which is where the bool IsActive comes from. It gets/sets from triggercontroller to the plugin
I'm trying to make unity do all of the work with having the plugin just be a middle man to connect things and make it flow
I may not understand enough here to be of much help. All my mods go get the active vessel and then do things with it - so they only ever run when there is an active vessel, and they only ever do things to/for the active vessel. I've been considering at a change with Node Manager to detect when the active vessel has changed so that it does a better job of refreshing it's node list, but that's as close as I've gotten to even needing something like this.
thats whats weird is its not doing anything to the vessel
what does it mean to have a '?' after a type in a variable declaration?
its just getting information, and then telling an animation to play
? indicates the var is a nullable type
so bool? can have three values: true, false, and null but bool can only have true or false
only for C#
Ahhh, gotcha. That helps a bit
That being the case I think you could run into trouble when state == null
yeah thats what i was wondering, im not having any issues with it in game
everything so far has been in the triggercontroller
im working on figuring out what the miscommunication is
Have you fed it to ChatGPT yet?
but i appreciate the insight. def wanna make this easy to read, simple and something others can add to a parts mod and understand how to adjust it to fit their needs
i should do that
I may be wrong about my previous statement re state == null being a problem. I think I was to hasty there.
In fact I'm pretty sure I was. I think you're using it just fine now in so far as it shouldn't cause anything to blow up. No idea if it will also do what you want it to
good to know
i appreciate your feedback. its not functional right now so its a WIP script
but ill get it fully functional soon.tm
still amazed i got toggle notifications working
I looked at the code today to remember how to use Logger correctly lol
Here's an idea for you. Start out with a variable tracking the activeVessel.Guid. Set it to "" initially, then just check to see if the active vessel's Guid is == to it.
thats pretty clever
This way, the first pass and on any pass where the active vessel has changed the two won't be equal and you'll detect that so you can respond accordingly
Or you could do something similar with activeVessel.SimulationObject.GlobalId, except you'll be dealing with type IGGuid instead of string.
I assume that each vessel's Guid needs to be unique though, so the first one should work.
hm
if (FlightGlobals.ActiveVessel.id.ToString() != _activeVesselGuid)
{
_activeVesselGuid = FlightGlobals.ActiveVessel.id.ToString();
}
if (FlightGlobals.ActiveVessel.id.ToString() != _activeVesselGuid)
{
_activeVesselGuid = FlightGlobals.ActiveVessel.id.ToString();
}
now to figure out how the activevessels are id'd
is it activeVessel.SimulationObject.GlobalId ?
Munix you drunk?
LUL
lmao no my rat ran over my keyboard
LOL!
rat running over your keyboard
i hardly ever drink
but i like to get mead drunk
mead drunk is a chill drunk
I was at my best friend's wedding so things got a bit wild lol
as they should have
I'll drink to that!
found it
SimulationObjectModel class and IGuidIdentity
hm
well im using viewcontroller to find the active vessel now
like this? _activeVessel = GameManager.Instance?.Game?.ViewController?.GetActiveVehicle(true)?.GetSimVessel(true);
oh
//bool _isActive = _viewController.IsActiveVessel("");
// bool _isActive = _activeVessel.IsActive;
i was searching through viewcontroller trying to figure out what to use
so that should work then
sorry i took a while, but can confirm i see the tanks in the OAB now :)) time to make something with them!
im experimenting with the center of mass/thrust/gravity so theyll be intersting to use in 0.1.2 for now
got some minor things to report:
- if you try to attach the tanks radially, they have a bit of an angle to them. don't know if its a problem with the SP-701 or the AT-CRS tho
- the SP-701's stringers don't exactly line up with the attach point (which is very minor and unimportant, but bugs me a bit nonetheless haha)
- some of the tanks seem to sometimes not get a green outline around them when hovering over them
i'm in the middle of doing a mission using them rn, so i'll let you know if i run into anything else!
odd. no worries. i appreciate the feedback!
-some of the tanks seem to sometimes not get a green outline around them when hovering over them -the SP-701's stringers don't exactly line up with the attach point (which is very minor and unimportant, but bugs me a bit nonetheless haha)
these are known and I have a fix for it coming with 0.1.3
if you try to attach the tanks radially, they have a bit of an angle to them. don't know if its a problem with the SP-701 or the AT-CRS tho
this I'll investigate as I may have accidently added some angle on the srfAttach
@quartz dagger I see.
so the reason it's getting the angle is because of the mesh that is on AT-CR5. I'll rework the mesh to get it to not angle stuff like that
trying to get the frost/mist color correct.
[Info : FFT] fuelContainer: KSP.Sim.ResourceSystem.ResourceContainer
[Info : FFT] fuelLevel: 0
[Info : FFT] _animator: CV401(Clone) (UnityEngine.Animator)
[Info : FFT] _fuelResourceIdResource[ID9]
[Info : FFT] _isActive: False
[Info : FFT] _wasActive: False
[Info : FFT] TriggerController has started.
[Error : FFT] _moduleResourceCapacities or _moduleResourceCapacities.OABPart or _moduleResourceCapacities.OABPart.Containers is null
[Info : FFT] CV401 not found
[Info : FFT] TriggerController has started.
[Error : FFT] _moduleResourceCapacities or _moduleResourceCapacities.OABPart or _moduleResourceCapacities.OABPart.Containers is null
[Error : FFT] _moduleResourceCapacities or _moduleResourceCapacities.OABPart or _moduleResourceCapacities.OABPart.Containers is null
[Info : FFT] CV401 not found```
hm
FFT will be part of the Devblog series. Devblog series covers all the mods I'm working on. I'm going to go into what I've been doing with KERN, FFT, and Toggle Notifications. Devblog #3 should be out by Friday on youtube.
2. If the GameObject is found, it will be stored in the CV401 variable for later use, reducing the need for calling GameObject.Find() repeatedly in each frame.```
there's so much that goes into making sure parts are where they need to be, when they need to be, in the state they need to be in, with the correct resources... etc
so it turns on but doesnt turn off based off fuel level. hm
I'm doing my floats wrong and my script isn't getting the fuel value. The animation runs when I hardcode the FuelLevel float to 1. The animation doesn't run when I hardcode the FuelLevel float to 0 in the animator. FuelLevel is a parameter that is used by CoolingVFX_ON, CoolingVFX_OFF, and CoolingVFX_LOOP
VesselFuelLevelPropertyWatcher <-- does all the fuel calculations
Mmmmmh smoky
using this as the inner layer VFK
VFX*
trying to figure out how a "frosty fog" looks
and not a smoky fog
last piece of the puzzle:
private void FixedUpdate()
{
IResourceContainer fuelContainer = _moduleResourceCapacities.OABPart.Containers[0];
Logger.LogInfo("fuelContainer: " + fuelContainer);
UpdateFuelLevel(fuelContainer);```
fuelContainer = specific type of resource in the game
fuelLevel = float value with current amount of fuel in the container
private void UpdateFuelLevel(IResourceContainer fuelContainer)
{
float fuelLevel = _fuelLevelWatcher != null ? (float)(_fuelLevelWatcher.GetValueDouble() / 100.0) : (float)fuelContainer.GetResourceStoredUnits(_fuelResourceId);
_animator.SetFloat("FuelLevel", fuelLevel);
}```
How I'm attempting to do the float
current build:
https://github.com/cvusmo/FFT/tree/dev
Only using three scripts.
FFTPlugin.cs
SizesUI.cs
TriggerController.cs
Well, found out how NOT to do that. Now I'm looking at using the dV to update the animation.
Need to figure out how the game does these calculations. Once I figure that out, then I can accurately use the float FuelLevel to update the animations
private void UpdateFuelLevel(float deltaTime)
{
// current DeltaV
double currentDeltaV = GetCurrentDeltaV();
double deltaVConsumptionRate = _engine.CalculateDeltaVFuelConsumption(currentDeltaV);
float fuelConsumed = deltaVConsumptionRate * deltaTime;
float fuelRemaining = _stageFuelLevelWatcher.GetValueFloat() - fuelConsumed;
if (fuelRemaining < 0)
{
Logger.LogError("No Fuel.");
fuelRemaining = 0;
}
float maxFuel = GetMaxFuel();
FuelLevel = fuelRemaining / maxFuel;
_animator.SetFloat("FuelLevel", FuelLevel);
Logger.LogInfo("Fuel level: " + FuelLevel);
UpdateAnimatorState();
}```
Sorry I didn't follow this thread very closely, but are you trying to compute the current fuel percentage of the current stage of your vessel?
yeah. I think it's the last piece of the puzzle. heres's what I'm attempting to do:
- FFTPlugin detects 3 different gamestates, if it is one of those 3, it kicks off the TriggerController.
- TriggerController checks to see if the part has TriggerController attached. If not, it adds it. If it does, all good.
- Various if/else to update the fuel level and activate the animations based on this:
private void UpdateAnimatorState()
{
if (FuelLevel > 0.8f)
{
_animator.Play("CoolingVFX_LOOP");
}
else if (FuelLevel <= 0.8f && FuelLevel > 0)
{
_animator.Play("CoolingVFX_OFF");
}
else
{
_animator.Play("CoolingVFX_ON");
}
}```
1. FuelLevel is a float that is a parameter in the animator. It is set to 0.
2. fuelPercentage is checked to make sure it's not 0.
3. FuelLevel is then used to calculate the current fuel
The value that FuelLevel gets from:
FuelLevel = (float)fuelPercentage / 100.0f;
needs to be the float that is updated consistently for the Animator to know when to switch to CoolingVFX_ON, CoolingVFX_LOOP, and CoolingVFX_OFF
This is what I got from the last time I ran the mod when testing:
```[Info :ToolbarBackend] App bar creation event started: OAB
[Info : FFT] Attached to GameObject: CoolingVFX
[Info : FFT] Found CoolingVFXCoolingVFX
[Info : FFT] TriggerController has started.
[Info : FFT] Attached to GameObject: CoolingVFX
[Info : FFT] Found CoolingVFXCoolingVFX
[Info : FFT] TriggerController has started.
[Info : FFT] CV401 found: CV401 (UnityEngine.GameObject)
[Info : FFT] ActiveSimVessel: Fly Safe-1
[Info : FFT] Fuel level: 0```
I've tried to get the fuel level from different ways, mainly IResourceContainer but when I was testing I realized I just need to find out what the current dV is and when the current dV in the stage goes below 80% then it turns the animation off
private void UpdateFuelLevel()
{
double fuelPercentage = _stageFuelLevelWatcher.GetValueDouble();
if (fuelPercentage < 0)
{
Logger.LogError("Invalid active vessel or vessel with 0 fuel tanks.");
}
else
{
FuelLevel = (float)fuelPercentage / 100.0f;
_animator.SetFloat("FuelLevel", FuelLevel);
Logger.LogInfo("Fuel level: " + FuelLevel);
}
}```
This is what returned a value of fuel level 0.
Have you tried using Game?.ViewController?.GetActiveVehicle(true)?.GetSimVessel(true).StageFuelPercentage ? (again sorry if you already tried something like this, it's just that I saw this property in the game's API)
not sure if i have or haven't to be honest but ill see if it works
private void UpdateFuelLevel()
{
_vesselComponent.RefreshFuelPercentages();
double fuelPercentage = _vesselComponent.StageFuelPercentage;
if (fuelPercentage < 0)
{
Logger.LogError("Invalid active vessel or vessel with 0 fuel tanks.");
}
else
{
FuelLevel = (float)fuelPercentage;
_animator.SetFloat("FuelLevel", FuelLevel);
Logger.LogInfo("Fuel level: " + FuelLevel);
}
}
About to test this out, i always overcomplicate things
Using a getter has side effects. Does the way I've wrote it not have side effects?
No im saying the other way around
Yours has side effects of setting an animator parameter
Getters dont usually have side effects
I don't know what a getter is or how it works
nevermind i do
my brain is tired
give me a sec and i rewrite it
something like this?
public float FuelLevel
{
get
{
_vesselComponent.RefreshFuelPercentages();
double fuelPercentage = _vesselComponent.StageFuelPercentage;
if (fuelPercentage < 0)
{
Logger.LogError("Out of Fuel." + fuelPercentage);
return 0f;
}
else
{
float level = (float)fuelPercentage;
_animator.SetFloat("FuelLevel", level);
Logger.LogInfo("Fuel level: " + level);
return level;
}
}
}```
Yeah
It'll also show users when they need an update
Keep it pointing towards the master version check
I find it interesting that hebaru is the one who did this pr, though he basically knows the swinfo structure completely
he's done it once for me before iirc
which means my .zip is probably wrong
pushing v0.1.2.1 to fix that issue
(though in swinfo it'll just be 0.1.2)
"mod_id": "FFT",
"author": "cvusmo",
"name": "FFT",
"description": "Fancy Fuel Tanks",
"source": "https://github.com/cvusmo/FFT",
"version": "0.1.2",
"version_check": "https://raw.githubusercontent.com/cvusmo/FFT/Master/FFT/swinfo.json",
"dependencies": [
{
"id": "SpaceWarp",
"version": {
"min": "1.1.1",
"max": "*"
}
}
],
"ksp2_version": {
"min": "0.1.0",
"max": "*"
}
}
well attemping to send it to spacedock
[Error : FFT] _animator is null in FixedUpdate
[Error : FFT] _animator is null in FixedUpdate
[Error : FFT] _animator is null in FixedUpdate
[Error : FFT] _animator is null in FixedUpdate
private void FixedUpdate()
{
_vesselComponent = Vehicle.ActiveSimVessel;
if (_animator != null)
{
_animator.SetBool("_isActive", _isActive);
}
else
{
Logger.LogError("_animator is null in FixedUpdate");
return;
}
if (_isActiveVessel != null)
{
Logger.LogInfo("_isActiveVessel.GetValueBool(): " + _isActiveVessel.GetValueBool());
IsActive = _isActiveVessel.GetValueBool();
}
else
{
Logger.LogError("_isActiveVessel is null in FixedUpdate");
return;
}
if (_wasActive && !_isActive)
{
DisableCoolingEffects();
}
_wasActive = _isActive;
}```
I haven't been able to figure out how to get the animator to work with the script now. sighs
@dreamy escarp whenever you get a chance, i'm not sure. im gonna google some more and see if i can find a tutorial on setting up animations properly. im 99.9% sure i messed up setting them up in unity cause the TriggerController class should be working fine
Do you ever set the animator?
And how do you set it in the script
Do you ever do gameobject.FindComponent<Animator>()
thats in awake()
Where is the script attached to
I dont think getcomponent in parent is recursive
Just make it a public field and set it w/in unity
Note: GetComponentInParent returns only the first matching component found, and the order that the components are checked on any individual GameObject is not defined. Therefore, if there are more than one of the specified type that could match on any individual GameObject, and you need to find a specific one, you should use Component.GetComponentsInParent and check the list of components returned to identify the one you want.
thats from unity. so does that mean that it can only go up to one parent?
No, it is recursive
That it goes up to all parents
oh okay cool
Now just set the animator in the inspector
so it works how i think it should
so thats on CV401 the parent of everything. when you say set the animator in the inspector, you're referring to the actual thing called Animator, correct?
No, im saying on the script thing you made
oh
Drag the cv401 to the field in the scrilt
Screenie?
but its on CoolingVFX
Unfold everything rq
What is vfx01?
its from the TriggerVFXFromAnimation script in ksp i found
i dont think i can post the code in here
Fait
but the class is called TriggerVFXFromAnimation
I am confused kinda
so what it does is use particle system to turn a vfx on or off
No, I was meaning related to your issue
essentially its the same thing as this:
public void StartParticleSystem()
{
if (_particleSystem != null)
{
_particleSystem.Play();
}
else
{
Logger.LogError("_particleSystem is null in _particleSystem.Play");
}
}
public void StopParticleSystem()
{
if (_particleSystem != null)
{
_particleSystem.Stop();
}
else
{
Logger.LogError("_particleSystem is null in _particleSystem.Stop");
}
}```
yeah im confused as well
_animator is returning null and i dont know why
Did you make _animator public like I was trying to say
and its doing it in FixedUpdate
it is public now, i havent tested it yet
public void Awake()
{
Logger = FFTPlugin.Logger;
Logger.LogInfo("Attached to GameObject: " + gameObject.name);
_triggerVFX = GetComponent<TriggerVFXFromAnimation>();
_particleSystem = CoolingVFX.GetComponent<ParticleSystem>();
Animator animator = GetComponentInParent<Animator>();
if (animator == null)
{
Logger.LogError("Animator component not found in parents.");
}
_animator = animator;
_isActiveVessel = new IsActiveVessel();
_vesselComponent = new VesselComponent();
Logger.LogInfo("TriggerController has started.");
}```
i made _animator = animator; so that if it wasn't null it'd still work but if it was null it'd show me it was null, that was the idea
Alright comment out the getcomponent
But i dont see an animator field in the inspector
Did you update the script in unity?
give me a second to update it all
Once you do send me a screenie of the triggercontroller on the gameobject
The animator is attached to CV401
the triggercontroller script is attached to CoolingVFX
So ... there should be a field called animator in the inspector if you made the field publuc
No it idnt
hm
private Animator _animator
Ahhh
fixed it and updating
Alright once you do that send me a screenie of it in the inspector again
Also, this is how I've been updating:
- Sripts > TriggerController > Reimport
- Assets > FFT > Reimport
- Packages > KSP.exer > Reimport
is there a better way to do that?
Thats not the issue
Unfold trigger controller
... (me realizing unity is dumb)
Rename it from _animator to animator please I think unity auto hides fields starting w/ an underscore
Then send me a screenie of the exact same place after that change
Itd be easier for me to help if I were home and could get into a vc w/ ya but aaaa
no worries
i appreciate the help
im about to go watch some football. messi is playing tonight
Okay ... unity ... wtf
@dreamy escarp why isnt the animator field showing in the inspector
the script is probably faulty in some way
reimport the dll
or build a new one and import it
did that already.
Sripts > TriggerController > Reimport
Assets > FFT > Reimport
Packages > KSP.exer > Reimport
thats how ive been updating when i make a change to triggercontroller.cs
including rebuilding the .dll
ah
nop
i think i know where i screwewd up
xD
that look correct?
I'm not finding the .dll to add to my FFT Def?
Fixed that
Apologies I am somewhat busy
all good
TypeLoadException: Could not load type of field 'TriggerController:<Logger>k__BackingField' (8) due to: Could not load file or assembly 'BepInEx, Version=5.4.21.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. assembly:BepInEx, Version=5.4.21.0, Culture=neutral, PublicKeyToken=null type:<unknown type> member:(null) signature:<none>
ah
so i need to add BepInEx into this now?
cause im using BepInEx.Logging in TriggerController to figure out wtf is wrong with it
unless i remove it from TriggerController and just reference it back to the plugin and let the plugin do the logging
not sure how i need to set those up, but it seems to be working
time to eat. any recommendations just ping me thanks for the help cheese and lux!
[Info : FFT] _isActiveVessel.GetValueBool(): True
[Info : FFT] IsActive set to true
[Info : FFT] _isActiveVessel.GetValueBool(): True
[Info : FFT] IsActive set to true
[Info : FFT] CV401 not found
NullReferenceException: Object reference not set to an instance of an object
at FFT.FFTPlugin.Update () [0x0010f] in C:\Users\nicho\source\repos\FFT\FFTProject\FFTPlugin.cs:70
(Filename: C:/Users/nicho/source/repos/FFT/FFTProject/FFTPlugin.cs Line: 70)```
alright now its just fixing my plugin
GameObject CoolingVFX = CV401.transform.Find("CoolingVFX")?.gameObject;
public GameObject CV401;```
Still more to do with it. But watching Messi. I'll post more later today if you're available in like 2 hours
probably wont, it will be 2am here xD
@dreamy escarp when you get a chance, this is all the animation stuff and how I've set it up in Unity.
FFTPlugin does checks to see what the gamestate is in, if it's in flightview, launchpad, or runway it then triggers the TriggerController to start
FuelTanks is a library of all the FuelTanks.
public class FuelTanks : MonoBehaviour
{
[SerializeField]
public GameObject CV401;
//more to be added once I get this working
}```
FFTPlugin
This is what the log shows;
[Info : FFT] _isActiveVessel.GetValueBool(): True
[Info : FFT] IsActive set to true
[Simulation] [Staging][CommandEntry]<7950be>: MovePartsToStage(stageIndex 0, parts 1, partIndex 0) - Have Stages: 1
[Simulation] [Staging][CommandEntry]<7950be>: MovePartsToStage(stageIndex 0, parts 1, partIndex 0) - Have Stages: 1
[Simulation] [Staging][CommandEntry]<7950be>: MovePartsToStage(stageIndex 0, parts 1, partIndex 0) - Have Stages: 1
[Info : FFT] _isActiveVessel.GetValueBool(): True
[Info : FFT] IsActive set to true```
No animation is played though
From TriggerController line 113
FFTPlugin.Logger.LogInfo("IsActive set to true");```
I think I know what's happening... !_wasActive is causing it to not play because it was not previously active. its the first time its actually active
- the bool _isActive set to false here
public class TriggerController : MonoBehaviour
{
public TriggerVFXFromAnimation _triggerVFX;
public Animator animator;
public ParticleSystem _particleSystem;
public IsActiveVessel _isActiveVessel;
public VesselComponent _vesselComponent;
public bool _wasActive;
public bool _isActive;```
2. the value of _isActive causes IsActive bool to always return false
```cs
public bool IsActive
{
get { return _isActive; }
set
{```
3. I want to know if the current vessel is active so I can simplify it this way
```cs
public bool IsActive
{
get { return _isActiveVessel.GetValueBool(); }
set
{```
That means now it's checking for the active vessel and it will return that value so it's not a hardcoded value in the script
public void FixedUpdate()
{
_vesselComponent = Vehicle.ActiveSimVessel;
if (animator != null)
{
animator.SetBool("_isActive", _isActiveVessel.GetValueBool());
}
else
{
FFTPlugin.Logger.LogError("animator is null in FixedUpdate");
return;
}
if (_isActiveVessel != null)
{
FFTPlugin.Logger.LogInfo("_isActiveVessel.GetValueBool(): " + _isActiveVessel.GetValueBool());
IsActive = _isActiveVessel.GetValueBool();
}
else
{
FFTPlugin.Logger.LogError("_isActiveVessel is null in FixedUpdate");
return;
}
if (_wasActive && !_isActiveVessel.GetValueBool())
{
DisableCoolingEffects();
}
_wasActive = _isActiveVessel.GetValueBool();
}```
Made the changes in the FixedUpdate.
I think this will work now?
[Info : FFT] _isActiveVessel.GetValueBool(): True
[Info : FFT] IsActive set to true
[Simulation] [Staging][CommandEntry]<7950be>: MovePartsToStage(stageIndex 0, parts 1, partIndex 0) - Have Stages: 1
[Simulation] [Staging][CommandEntry]<7950be>: MovePartsToStage(stageIndex 0, parts 1, partIndex 0) - Have Stages: 1
[Simulation] [Staging][CommandEntry]<7950be>: MovePartsToStage(stageIndex 0, parts 1, partIndex 0) - Have Stages: 1
[Info : FFT] _isActiveVessel.GetValueBool(): True
[Info : FFT] IsActive set to true```
IsActive was being set to true because _isActive (the bool it's getting) is set to false. I changed it to use the value of _isActiveVessel that way it checks if the Vessel is active
this should make it work now, right?
or at least run the Awake/Start
no worries. uhh so the whole idea is that it's checking to see if the vessel is active and has the correct gameobject on it. if it does, then it runs the animation if it meets requirements else it stops the animation
i think
you already can put the monobehaviour on the parts correct?
it can be pretty simple if so ngl
i can put them on, im importing the new build
basically what you can do is
on each part you add that monobehaviour
actually i think theres an easier way
a sec i'll make some cs files for you
dw its nothing complicated its just that you need to have these 3 correctly setup if you want them to work
how are you getting the total fuel of the part btw?
public float FuelLevel
{
get
{
_vesselComponent.RefreshFuelPercentages();
double fuelPercentage = _vesselComponent.StageFuelPercentage;
if (fuelPercentage < 0)
{
FFTPlugin.Logger.LogError("Out of Fuel." + fuelPercentage);
return 0f;
}
else
{
float level = (float)fuelPercentage;
animator.SetFloat("FuelLevel", level);
FFTPlugin.Logger.LogInfo("Fuel level: " + level);
return level;
}
}
}```
using fuel percentage
but thats the percentage of the whole stage no?
not sure but its looking for the componenet on the vessel, and it specifically is trying to find CV401
which is how i think it works
but i could be wrong
it also hasnt worke dyet
heh, doesnt seem like it
at least from that code
oh xD
im not giving you the keys to the treasure
but a good Hint
Oh and rename the namespace to something of your liking xD
dont leave it as SORRY
you just attach that to your parts in Unity
set the Animation Curve
being X fill percentage and Y the Opacity
X = 0 Empty, 1 Full
ah
can you send me the .cs?
so i can see it?
you can probably still use it, and tbh since you had a bit of work in it its better that you use it xD
so it doesnt go to waste
thats what i thought cause it is the bread and butter of it
on Module_TriggerVFX you add a reference to Trigger Controller
but does it need to be in FFT.Modules?
yeah whatever you feel like fits
I'm learning how to structure things and I think I'm using the _someValue correctly
doesnt need to be that but its what the game uses 
still not 100% on how C# should be written
well
you use _someValue usually for properties, im using it a bit wrong there but again
its what the game uses
oh i was just saying _someValue as an example
i was mainly meaning _useOfThisLineThing
usually
public float SomeValue;
private float someValue;
private float _someValue
{
get => someValue;
set => someValue = value;
}
this is the more correct use
@gray fable can back me up on this one im not the best at naming conventins xD
thats what its called, naming conventions
i thought i was doing it right but i gotta look it up again
but tbh its not that important 
i wanna make sure these scripts use the naming conventions properly
i know its not important, buttttt I like neat and organized and if there's a standard, I just like to do things the "right" way
to be fair private properties don't make much sense
monobehaviour fields start lowercase

is there a link any of oyu have that goes over naming conventions?
so no convention xD
yeah that's another thing, Unity has other conventions than regular C#
or a standard you all know of?
TriggerController triggerController;
public override void OnInitialize()
{
base.OnInitialize();
if (PartBackingMode == PartBackingModes.Flight)
{
triggerController = GetComponentInChildren<TriggerController>();
}
}
btw do something like this to save your TriggerController reerence
https://github.com/ktaranov/naming-convention/blob/master/C%23 Coding Standards and Naming Conventions.md here is a bit more comprehensive guide
btw munix, wtf is a recorder?
public record PhysicalAddress(
string Street,
string City,
string StateOrProvince,
string ZipCode);
record is a class-like value type
i see ok, so kinda like a wrapper
two instances of a record are the same if the values of all their fields are the same
oh thats cool wtf
lmao
how is it going?
im reworking my original code
using System.Collections.Generic;
using UnityEngine;
public class FuelTankDefinitions : MonoBehaviour
{
[SerializeField]
private List<GameObject> fuelTankDefintions;
private Dictionary<string, GameObject> fuelTanksDict = new Dictionary<string, GameObject>();
private void Awake()
{
foreach (var tank in fuelTankDefintions)
{
fuelTanksDict[tank.name] = tank;
}
}
public GameObject GetFuelTank(string tankName)
{
if (fuelTanksDict.TryGetValue(tankName, out var tank))
{
return tank;
}
return null;
}
}```
Making sure the structure works so that I can easily search for the parts and easily add them into the script
I think this is the best way to do it as the game does it with it's use of definitions
its so the plugin can find the correct part otherwise I have to add BepInEx.dll to the FFTDef
oh yeah you def dont need that
heres why I like it though
i mean depends, you probably want tot est it on unity
I can easily look up and see what parts I've added or not added
if so you might need it
so on my end it makes my life a bit easier cause I know exactgly where to look when I add parts
and the idea is, "I add a fuel tank, now I just use triggercontroller to find that"
thats my logic behind it
with the think i sent u
it works like any other module
you just add it to your parts
public void GetFuelTanks()
{
CV401 = fuelTankDefintions.GetFuelTank("CV401");
}
void Awake()
{
fuelTankDefintions = FindObjectOfType<FuelTankDefinitions>();
GetFuelTanks();
if (CV401 == null)
{
Logger.LogInfo("CV401 not found in FuelTanks.");
}
}```
That's whats in the plugin
and it will do the ingame work for you
PartComponentModule_TriggerVFX ?
Module_TriggerVFX
build the DLL with the 3 files i sent you
and import into unity
and you'll see them
no need for bepinex
the reason i was using bepinex is for the logging
so i could see what was wrong with my code and figure out how to fix it
where does Debug.Log export to?
KSP2.log
i mean
you can use Logger.Log, but i think it would be easier for you to work if you could have everything working both on unity and the game
i agree
i just didn't know how debug.log worked but knew how bepinex.logging worked
so i went with what i knew
so module_trigger is added
i think it should go on the parent object
not on coolingvfx though
ok
now
your missing something that i missed i think
a sec
let me see
huh thats wierd
there should be a data_TiggerVFX there
On btw
add that to the root partName folder
no im sorry
move
Module_TriggerVFX in unity
in your part
to the same place you put all other Module_
well not rlly
it should show an animation curve there
but im looking into it a sec
either way
Add this somewhere on your Module_TriggerVFX
basically you're automatically searching for any TriggerController thats on the part
on all its children
xD
btw i change GetComponent to GetComponentInChildren
TriggerController triggerController;
public void OnInitialize()
{
base.OnInitialize();
if (PartBackingMode == PartBackingModes.Flight)
{
triggerController = GetComponentInChildren<TriggerController>();
}
}```
I get error cs0507 if i attempt to override it:
using KSP.Sim.Definitions;
using UnityEngine;
namespace FFT.Modules
{
internal class Module_TriggerVFX : PartBehaviourModule
{
public override Type PartComponentModuleType => typeof(PartComponentModule_TriggerVFX);
[SerializeField]
public Data_TriggerVFX _dataTriggerVFX;
TriggerController triggerController;
public override void OnInitialize()
{
base.OnInitialize();
if (PartBackingMode == PartBackingModes.Flight)
{
triggerController = GetComponentInChildren<TriggerController>();
}
}
public void AddDataModules()
{
base.AddDataModules();
this._dataTriggerVFX ??= new Data_TriggerVFX();
this.DataModules.TryAddUnique<Data_TriggerVFX>(this._dataTriggerVFX, out this._dataTriggerVFX);
}
public void OnModuleFixedUpdate(float fixedDeltaTime)
{
base.OnModuleFixedUpdate(fixedDeltaTime);
double FillRatio = 0;
int count = 0;
foreach (var container in part.Model.Containers)
{
foreach (var ResourceID in container)
{
count++;
FillRatio = container.GetResourceFillRatio(ResourceID) / count;
}
}
float opacity = _dataTriggerVFX.VFXOpacityCurve.Evaluate((float)FillRatio);
//Set VFX Opacity Here
}
}
}
huh thats wierd
a sec
i mean you already have it there no?
on the start of the file
i added it
yes
its giving CS0507
because i cant override a protected inherited memeber
member*
from PartBehaviourModule
PartBehaviourModule.OnInitialize I can't override is what I think its saying
well idk
a sec
i think you'll need to publicize the game's dlls
its easy
ok so
can you right click your project and go edit project files?
no wonder you've had to make so many workarounds to get what you wanted xD
yup
the one below it
a sec
below the HintPath add this
<Publicize>true</Publicize>
<Private>false</Private>
the hint path is at the bottom of the file
oh not even need to reload
yeah cuz
the method ur trying to access is protected
meaning that you can only access it inside the Assmebly-CSharp dll
but thats little trick makes everything public
its pretty much the base of KSP2 modding as of now lmao
almost everything in KSP2 code is private or protected for some reason 
thats incredible and so simple
yeah
ive noticed
so ive had to find ways to make it work
this makes life so much easier
ok so bach to the modules, should be easy now
to give a little contex i'll explain whats happening here
id look at a module and it'd say "private" on something i needed and id have to find where it came from, so i could figure out how to use it
lol
public override void OnInitialize()
//This is called everytime the module gets added to a part in game, be it in OAB or Flight or watever else they add in the future
if (PartBackingMode == PartBackingModes.Flight)
//PartBackMode is present in all Module_ (and some more) basically tells you where this part is being instantiated, we only want to mess with it if its on Flight so we check if its on Flight Mode
public void OnModuleFixedUpdate(float fixedDeltaTime)
//This is called (almost) every frame on Flight Mode, since we only want to mess with flight mode we use this
double FillRatio = 0;
int count = 0;
foreach (var container in part.Model.Containers)
{
foreach (var ResourceID in container)
{
count++;
FillRatio = container.GetResourceFillRatio(ResourceID) / count;
}
}
//This gives you the fuel percentage, FillRatio is your fuel from 0-1
float opacity = _dataTriggerVFX.VFXOpacityCurve.Evaluate((float)FillRatio);
//This (if i can get it to show in your unity) evaluates that fuel percentage with a AnimationCurve that you edit on Unity, basically making FillRatio bein X and returning the Y
there we go
wtf how did you do it?
either way, X 0 is empty and X 1 is full
so like that u have 100% opacity on empty and 0% opacity on Full
hm
so i need it to bee 0 when the tank is at 80%
because the animation isn't going to run the entire time
as the tank would lose its frost/ice as it goes up in atmo
before heat is added this is how i wanted to simulate it
eventually i want to make it calculate both fuel level and temperature
so as fuel goes down, and the temperature rises on the tank, the animation responds accordingly
yup!
show me!
this one doesnt
how do i make the curve do what i described? when fuel tank is 80% the animation opacity is 0?
ah
time is fuel
thqats what i was trying ot figure out but couldnt ask correctly
sorry im multitasking
and my brain is struggling today
should work now
time should be 0.8
value should be 0
then time should be 1 and value should be 1
or that swapped
if you want at 100% fuel for it to be 1 opacity yeah
seems right
now
on the code you do watever you need, you could so something like
- If opacity <= 0 Stop Trigger Controller Effects
- if opacity > 0 AND Trigger Controller has not started Start Trigger Controller
- Update TirggerController opacity
thats been done by TriggerController. It has all of that logic in it
then just carry over the opacity to it
to enable/disable the animations, disable/enable emission etc
ah
i see some of this logic in the module isn't how i want it to be
so i have to adjust it
basically gutting triggercontroller into module_triggervfx because now module_triggervfx does the functions that triggercontroller had
yeah i mean it should be on TriggerVFX ideally
but it can be in other scripts theres not much diffrence
migrating methods and such
itll condense things and create a standard for part modding
so when others start part modding we can be like "here you go"
and if theres issues, its easy for everyone to understand whats happening so we can help troubleshoot errors
yup!
which you gave me templates earlier
i used them, couldnt figure out how to get it to work cause errors, so i went down a rabbit hole to get it to work
then all i had to do was change the hint thing
think i got it all moved
@dreamy escarp hows that look after i merged them?
very good if it works 
the whole idea behind the module was for you not to use Animators tho
the TriggerVFX can controll everything on its own
animators are best used for actual animations
but check if it works!
if it works cool
definitely want to simplify it but friday (tomorrow) im hoping to release 0.1.3
[Info : FFT] IsActive set to false
[Error : FFT] _particleSystem is null in DisableEmission
NullReferenceException: Object reference not set to an instance of an object
at FFT.Modules.Module_TriggerVFX.set_IsActive (System.Boolean value) [0x000b8] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:125
at FFT.Modules.Module_TriggerVFX.FixedUpdate () [0x00088] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:193 ```
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] TriggerController has started.
[System] Property [isVisible] already found in context!
[System] Property [isVisible] already found in context!
[System] Property [isVisible] already found in context!
[Info : FFT] _isActiveVessel.GetValueBool(): False
[Info : FFT] IsActive set to false
[Error : FFT] _particleSystem is null in DisableEmission
Uploading Crash Report
NullReferenceException: Object reference not set to an instance of an object
at FFT.Modules.Module_TriggerVFX.set_IsActive (System.Boolean value) [0x000b8] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:125
at FFT.Modules.Module_TriggerVFX.FixedUpdate () [0x00088] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:193
(Filename: C:/Users/nicho/source/repos/FFT/FFTProject/Modules/Module_TriggerVFX.cs Line: 125)
well it says what like is giving the error
it cant find the particlesystem
because particlesystem is attached to coolingvfx and not cv401 which has the module attached to it
unless
i just move the particle system and everything to CV401
but thats not how i want to do it
i want to have a gameobject that has the CoolingVFX so I can add it or not add it to other fuel tanks
actually
i can just change GetComponentInChildren because that only looks for a child
maybe transform.Find? hm
|______model
|_______CV401
|______CoolingVFX
|______mesh
|_____col```
it should have found it but it didnt
so it should find
ah
it doesnt know what to look for
public override void OnInitialize()
{
base.OnInitialize();
if (PartBackingMode == PartBackingModes.Flight)
{
Awake();
}
}```
it looks but i didnt tell it what to find
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] _isActiveVessel.GetValueBool(): False
[Info : FFT] IsActive set to false
[Error : FFT] _particleSystem is null in DisableEmission
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401.prefab_4f1fc7ca-f8b2-471b-bd7a-4060ee81fcf8(Clone)
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401.prefab_4f1fc7ca-f8b2-471b-bd7a-4060ee81fcf8
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] _isActiveVessel.GetValueBool(): True
[Info : FFT] IsActive set to true
[Info : FFT] Was not previously active
[Info : FFT] Fuel level: 0```
public override void OnModuleFixedUpdate(float fixedDeltaTime)
{
base.OnModuleFixedUpdate(fixedDeltaTime);
double FillRatio = 0;
int count = 0;
foreach (var container in part.Model.Containers)
{
foreach (var ResourceID in container)
{
count++;
FillRatio += container.GetResourceFillRatio(ResourceID);
}
}
if (count != 0)
{
FillRatio /= count;
}
float opacity = _dataTriggerVFX.VFXOpacityCurve.Evaluate((float)FillRatio);
_fuelLevel = opacity;
FFTPlugin.Logger.LogInfo("opacity: " + opacity);
animator.SetFloat("FuelLevel", _fuelLevel);
FFTPlugin.Logger.LogInfo("Fuel level: " + _fuelLevel);
if (_fuelLevel < 0)
{
FFTPlugin.Logger.LogError("Out of Fuel. Fuel level: " + _fuelLevel);
}
if (IsActive)
{
if (!FuelLevelExceedsThreshold())
{
StopVFX();
}
else if (!animator.GetCurrentAnimatorStateInfo(0).IsName("CoolingVFX_LOOP"))
{
StartVFX();
}
}
else
{
StopVFX();
}
}```
@dreamy escarp hows that logic look?
its good!
sweet
im not adding another module yet but building the base of the Data_GravityVFX cause I want it to use the DynamicGravityForVFX
so I'm hoping I can just make a Data_GravityVFX.cs and then use it in the Module_TriggerVFX
namespace FFT.Modules
{
[Serializable]
internal class Data_GravityVFX : ModuleData
{
public override Type ModuleType => typeof(Module_TriggerVFX);
[KSPState]
public AnimationCurve CalculateGravity;
}
}
}```
just not sure about animationcurve etc
or if it needs its own module
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401.prefab_ea4170e1-d93c-4232-9de3-ff1bd516719e(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401.prefab_ea4170e1-d93c-4232-9de3-ff1bd516719e
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] opacity: 0
[Info : FFT] Fuel level: 0
[Info : FFT] opacity: 0
[Info : FFT] Fuel level: 0```
[LOG 16:33:43.755] [Flight] Switching To Vessel Fly Safe-1 ----------------------
[LOG 16:33:43.758] Toggle: BTN-Stability-Assist changed to: True - CurActive: BTN-Stability-Assist
[LOG 16:33:43.830] [System] Starting... completed in 0.0000s.
[ERR 16:33:43.877] [Physics] Object reference not set to an instance of an object
at FFT.Modules.Module_TriggerVFX.StopVFX () [0x00008] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:138
at FFT.Modules.Module_TriggerVFX.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x00140] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:113
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0
Forgot to set the opacity KEKW
public override void OnModuleFixedUpdate(float fixedDeltaTime)
{
base.OnModuleFixedUpdate(fixedDeltaTime);
double fillRatioSum = 0;
int count = 0;
foreach (var container in part.Model.Containers)
{
foreach (var resourceID in container)
{
FFTPlugin.Logger.LogInfo("ResourceID Before: " + resourceID);
FFTPlugin.Logger.LogInfo("opacity Before: " + count);
count++;
fillRatioSum += container.GetResourceFillRatio(resourceID);
FFTPlugin.Logger.LogInfo("ResourceID After: " + resourceID);
FFTPlugin.Logger.LogInfo("opacity After: " + count);
}
}
double fillRatioAverage = fillRatioSum / count;
float opacity = _dataTriggerVFX.VFXOpacityCurve.Evaluate((float)fillRatioAverage);
_fuelLevel = opacity;
FFTPlugin.Logger.LogInfo("opacity: " + opacity);
animator.SetFloat("FuelLevel", _fuelLevel);
FFTPlugin.Logger.LogInfo("Fuel level: " + _fuelLevel);
if (_fuelLevel < 0)
{
FFTPlugin.Logger.LogError("Out of Fuel. Fuel level: " + _fuelLevel);
}
if (IsActive)
{
if (!FuelLevelExceedsThreshold())
{
StopVFX();
}
else if (!animator.GetCurrentAnimatorStateInfo(0).IsName("CoolingVFX_LOOP"))
{
StartVFX();
}
}
else
{
StopVFX();
}
}```
Now, how to make this VFX look better:
@dreamy escarp why's it look how i want in scene:
but in Game it is way different?
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV411(Clone)
[Error : FFT] CoolingVFX GameObject is not assigned.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV411(Clone)
[Error : FFT] CoolingVFX GameObject is not assigned.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV411.prefab_d0ad7176-a66e-4109-ab2e-23363aee2668(Clone)
[Error : FFT] CoolingVFX GameObject is not assigned.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV411(Clone)
[Error : FFT] CoolingVFX GameObject is not assigned.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV421(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV421(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV421.prefab_5e4a86d9-9db3-4c91-b19d-0563d325f628(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV421.prefab_5e4a86d9-9db3-4c91-b19d-0563d325f628
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.```
[ERR 19:48:28.642] [Physics] Object reference not set to an instance of an object
at FFT.Modules.Module_TriggerVFX.StartVFX () [0x0000f] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:123
at FFT.Modules.Module_TriggerVFX.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x00139] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:111
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Successfully retrieved ParticleSystem.
[Error : FFT] Could not find TriggerVFXFromAnimation on CoolingVFX.
[Error : FFT] Could not find DynamicGravityForVFX on CoolingVFX.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV411(Clone)
[Error : FFT] CoolingVFX GameObject is not assigned.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV411(Clone)
[Error : FFT] CoolingVFX GameObject is not assigned.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV411.prefab_f6a3e0de-2ce7-4226-b9d8-9e41bf662759(Clone)
[Error : FFT] CoolingVFX GameObject is not assigned.
[Info : FFT] Module_TriggerVFX has started.```
at FFT.Modules.Module_TriggerVFX.StartVFX () [0x0000f] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:136
at FFT.Modules.Module_TriggerVFX.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x00139] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:124
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0
This is how it'll function until they release heating/cooling. I will be working on improving the VFX for next week's release
@acoustic shale name the part, right now I have it as RF-1 "Riffs Vents" 👍
and later today ill texture this
sorry just saw this umm honestly im not that good with naming stuff the name you already have is good enough for me but change it as you see fit
This is cool
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: RF1.prefab_089d957e-edd9-43f9-b1b5-868b4a7b9120
[Info : FFT] Successfully retrieved ParticleSystem.
[Info : FFT] Module_TriggerVFX has started.```
didnt have the animator attached LOL
@gray fable any idea why it looks massive in the VAB but on launchpad, its the correct size?
no clue, I mean I haven't even gotten a part into the game yet, so I'm not the best person to ask 😅
lol no worries. @dreamy escarp when you get a chance, not sure what i did here
prefab scale
thanks!
adding a second module to handle the new vent valve parts:
[ERR 16:57:49.015] [Serialization] Error converting value "FFT.Modules.Data_TriggerVFX, FFT, Version=0.1.3.0, Culture=neutral, PublicKeyToken=null" to type 'System.Type'. Path 'Vessels[0].parts[16].PartModulesState[4].ModuleData[0].DataType', line 7405, position 119.
[ERR 16:57:49.015] [Serialization] Error converting value "FFT.Modules.Data_TriggerVFX, FFT, Version=0.1.3.0, Culture=neutral, PublicKeyToken=null" to type 'System.Type'. Path 'Vessels[0].parts[16].PartModulesState[4].ModuleData[0].DataType', line 7405, position 119.```
at FFT.Modules.Module_TriggerVFX.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x00088] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_TriggerVFX.cs:90
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Successfully retrieved ParticleSystems.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Successfully retrieved ParticleSystems.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401.prefab_8162aad4-1903-474b-b689-e9d13525c024(Clone)
[Info : FFT] Successfully retrieved ParticleSystems.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: CV401.prefab_8162aad4-1903-474b-b689-e9d13525c024
[Info : FFT] Successfully retrieved ParticleSystems.
[Info : FFT] Module_TriggerVFX has started.
[Info :ToolbarBackend] App bar creation event started: Flight
[Info :ToolbarBackend] Added appbar button: BTN-ToggleNotificationsFlight
[Info :ToolbarBackend] App bar creation event started: OAB
[Info : FFT] Attached to GameObject: CV401(Clone)
[Info : FFT] Successfully retrieved ParticleSystems.
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: RF2(Clone)
[Error : FFT] Could not find TelemetryComponent in parent.```
FFT.Modules.Module_VentValve.Awake () (at C:/Users/nicho/source/repos/FFT/FFTProject/Modules/Module_VentValve.cs:70)
UnityEngine.Object:Instantiate(GameObject)
<GenerateDragCubeCoroutine>d__11:MoveNext()
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
DragCubeGenerator:GenerateDragCube(GameObject, DragCube&)
KSP.Modules.Module_Drag:OnInitialize()
KSP.Sim.Definitions.PartBehaviourModule:Init()
KSP.Sim.impl.PartBehavior:Start()
[ERR 22:42:36.782] [Debug] System.NullReferenceException: Object reference not set to an instance of an object
at FFT.Modules.Module_VentValve.Awake () [0x000ab] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_VentValve.cs:70
at FFT.Modules.Module_VentValve.OnInitialize () [0x00026] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_VentValve.cs:41
at KSP.Sim.Definitions.PartBehaviourModule.Init () [0x0009f] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Sim.impl.PartBehavior.Start () [0x000e9] in <57799b60a4cd4df8b3c9aec811d65aed>:0 ```
[Info :ToolbarBackend] App bar creation event started: OAB
[Info : FFT] Attached to GameObject: RF2(Clone)
[Error : FFT] ParticleSystem assigned.
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Info : FFT] Attached to GameObject: RF2(Clone)
[Error : FFT] ParticleSystem assigned.
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Info : FFT] Attached to GameObject: RF2.prefab_294e300a-f7dd-4aa1-97bc-1a8fb5cba2a7(Clone)
[Error : FFT] ParticleSystem assigned.
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Info : FFT] Attached to GameObject: RF2.prefab_294e300a-f7dd-4aa1-97bc-1a8fb5cba2a7
[Error : FFT] ParticleSystem assigned.
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Error : FFT] _telemetryComponent is null.```
[ERR 16:39:41.928] [Physics] Object reference not set to an instance of an object
at FFT.Modules.Module_VentValve.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x00009] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_VentValve.cs:87
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0 ```
Trying to be helpful but when I read something wrong with being dyslexia you mock me for not understanding a word correctly like several and 7 and I get defensive thinking I read it right for you to attack me shame on you like I help with your mod in my own way
I don't see anything wrong there
@sick dagger That my point I haven't but yet in anorther chat
He went for the attack in ksp 2 General chat and jump on with everybody else when I said I read nate said science was several months away they were happy to point I was a idiot and that several dosent mean 7 months away even tho how I read is how I say it in my head so I can't read properly such a nice bloke
Can you send me an image of it? If your so keen on smearing him you must have some evidence correct?
@surreal loom Do you recall?
I'm not just Disappointed forget it he knows
Ok I'm super sorry but I'm not understanding you?
Best thing to do is message directly with an issue pertaining to an individual instead of in a devlog 

I wasn't even part of the conversation, but I have just read it a few minutes ago, and it's totally fine to misunderstand, but there were multiple people telling you over and over that "several" is not the same as "seven", and you kept repeating the same thing, or even saying that Nate said 10 months, so it's not that hard to see why they would think you were just trolling
It not hard to be me and think they were mocking me so why would I think there right no mater what they said
I said 10 months because it been 3 months then I thought he 7 more months
3 months since what? the game has been out for over 5 months now
Game been out 3 months then he said this in a Friday nate day and because he said several months I took that has 10 months but I guess I seen it wrong
and just to answer your question about the science update, you are right that there aren't too many parts in the game, but the update is not just about placing those parts in a tech tree and done, most of the time is probably spent working on models, textures and animations for the various science experiments, on the code for the whole science and research system, balancing the tech tree so that it's not too easy but not too difficult, writing and approving all the messages for when science is collected, etc
and there's a lot more that goes into a big update like that than even we modders see, so there's probably even more than what I said
But when they show nothing and say several months to me that me nothing
And I get several wrong dosent mean I should get attack
anyway if you wanna continue the discussion, we should do it in #🔵ksp2-general, and not here in a thread for a mod that this is completely unrelated to
I dident mean to I just seen him jump in and seen red I drop it
btw I definitely don't agree with the people in the IG server calling you names, just to be clear, I try to stay away from there myself because it's often full of toxic people
but I'm just saying I can understand why they might think you were trolling
I find it hard with words so I made it easy for people to laugh but I'm learning to try to control what I put rather then let my head talk first
you repeatedly said seven and refused to acknowledge that it said several and not seven. you never said you misread anything. you kept insisting it was seven. then you come into the KSP modding society and make a case about it. I said what I said. If you had an issue with it, DM me. You don't need to bring things from IG into this server.
at FFT.Modules.Module_VentValve.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x00009] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_VentValve.cs:87
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0 ```
I do recall. I posted above my response. I said what I said.
Makes some sense
Anyways, working on getting the new vfx working properly
Nice! Love the mod keep up the good work!
if (FFTPlugin.Instance._vesselComponent?.AltitudeFromTerrain == 0)
{
FFTPlugin.Logger.LogError("_vesselVehicle is null.");
return;
}
double altitudeFromSeaLevel = 0;
double altitudeFromTerrain = 0;
float aslCurve = 0;
float aglCurve = 0;
_ASLValve = (float)FFTPlugin.Instance._vesselComponent.AltitudeFromSeaLevel;
_AGLValve = (float)FFTPlugin.Instance._vesselComponent.AltitudeFromTerrain;
if (_ASLValve < altitudeFromSeaLevel)
{
aslCurve = _dataVentValve.VFXASLCurve.Evaluate(_ASLValve);
}
else
{
aslCurve = 0;
}
if (_AGLValve < altitudeFromTerrain)
{
aglCurve = _dataVentValve.VFXAGLCurve.Evaluate(_AGLValve);
}
else
{
aglCurve = 0;
}```
That's what I've been trying to use to get the current altitude of the vessel. It's obviously not working. @gray fable any suggestions?
it definitely should be working, since Falki uses it in MicroEngineer
your _vesselComponent is set correctly?
weird so falki does the same thing, i havent looked at microengineer
uhh
this is how I have _vesselComponent set up
#🔴mod-dev message
i didnt even see that! thank you
[Info :Flight Plan] GameState Transitioned: Invalid -> FlightView
[Info : FFT] Attached to GameObject: RF2.prefab_2ea057a8-40aa-47b8-a82a-2b657d235501(Clone)
[Info : FFT] ParticleSystem assigned.
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Info : FFT] Attached to GameObject: RF2.prefab_2ea057a8-40aa-47b8-a82a-2b657d235501
[Info : FFT] ParticleSystem assigned.
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Error : FFT] SurfaceEntry is null.
[Error : FFT] SurfaceEntry is null.```
[Info : FFT] Attached to GameObject: RF2(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info :Flight Plan] GameState Transitioned: Invalid -> FlightView
[Info : FFT] Attached to GameObject: RF2.prefab_9af349fe-aeb5-41f0-96a9-17fe72ec9b91(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Attached to GameObject: RF2.prefab_9af349fe-aeb5-41f0-96a9-17fe72ec9b91
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Error : FFT] altitudeAgl or altitudeAsl is null.```
@south girder
public override void OnModuleFixedUpdate(float fixedDeltaTime)
{
base.OnModuleFixedUpdate(fixedDeltaTime);
if (_altitudeAgl != null && _altitudeAsl != null)
{
_altitudeAgl.RefreshData();
_altitudeAsl.RefreshData();
_ASLValve = (float)_altitudeAsl.EntryValue;
_AGLValve = (float)_altitudeAgl.EntryValue;
}
else
{
FFTPlugin.Logger.LogError("altitudeAgl or altitudeAsl is null.");
return;
}
float aslCurve = _dataVentValve.VFXASLCurve.Evaluate(_ASLValve);
float aglCurve = _dataVentValve.VFXAGLCurve.Evaluate(_AGLValve);
animator.SetFloat("ASLValve", aslCurve);
animator.SetFloat("AGLValve", aglCurve);
if (_ASLValve < 0 || _AGLValve < 0)
{
FFTPlugin.Logger.LogError("_ASLValve closed: " + _ASLValve);
FFTPlugin.Logger.LogError("_AGLValve closed: " + _AGLValve);
}
if (IsActive)
{
if (aslCurve == 0 && aglCurve == 0)
{
StopVFX();
}
else if (aslCurve > 0 || aglCurve > 0)
{
StartVFX();
}
}
else
{
StopVFX();
}
}```
[EXC 21:37:01.683] NullReferenceException: Object reference not set to an instance of an object
FFT.MicroMod.Entries.AltitudeAgl.RefreshData () (at C:/Users/nicho/source/repos/FFT/FFTProject/MicroMod/Entries/SurfaceEntry.cs:35)
FFT.Modules.Module_VentValve.InitializeAltitudeEntries () (at C:/Users/nicho/source/repos/FFT/FFTProject/Modules/Module_VentValve.cs:188)
FFT.Modules.Module_VentValve.InitializeDataEntries () (at C:/Users/nicho/source/repos/FFT/FFTProject/Modules/Module_VentValve.cs:182)
FFT.Modules.Module_VentValve.Awake () (at C:/Users/nicho/source/repos/FFT/FFTProject/Modules/Module_VentValve.cs:52)
UnityEngine.Object:Instantiate(GameObject, Transform)
KSP.OAB.ObjectAssemblyPart:FinalizeLoad(ObjectAssemblyBuilderEvents, IObjectAssemblyAvailablePart)
KSP.OAB.ObjectAssemblyPartTracker:DMD<KSP.OAB.ObjectAssemblyPartTracker::OnPartPrefabLoaded>(ObjectAssemblyPartTracker, IObjectAssemblyAvailablePart, GameObject)
KSP.OAB.<>c__DisplayClass57_0:<LoadPartsAtInterval>b__0(GameObject)
KSP.Assets.<>c__DisplayClass11_0`1:<Load>b__1(AsyncOperationHandle`1)
DelegateList`1:Invoke(AsyncOperationHandle`1)
UnityEngine.ResourceManagement.ResourceManager:Update(Single)
MonoBehaviourCallbackHooks:Update()```
not sure why its coming back null
[Info : FFT] Module_TriggerVFX has started.
[Info : FFT] Attached to GameObject: RF2(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Attached to GameObject: RF2(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Attached to GameObject: RF2.prefab_9d2e1ef9-e25d-4125-bc64-c0259a589fdf(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Error : FFT] altitudeAgl or altitudeAsl is null.```
at FFT.Modules.Module_VentValve.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x00009] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_VentValve.cs:70
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0 ```
[Info : FFT] Attached to GameObject: RF2(Clone)
[Info : FFT] Attached to GameObject: RF2(Clone)
[Info : FFT] Attached to GameObject: RF2.prefab_a14bc0f5-6dca-4cee-a500-a4a437cb33d4(Clone)
[Info : FFT] Attached to GameObject: RF2.prefab_a14bc0f5-6dca-4cee-a500-a4a437cb33d4
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.```
[Info : FFT] Attached to GameObject: RF2(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Info : FFT] Attached to GameObject: RF2(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Info : FFT] Attached to GameObject: RF2.prefab_90f409e0-d5b8-4300-8b01-2a4769c84680(Clone)
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Info : FFT] Attached to GameObject: RF2.prefab_90f409e0-d5b8-4300-8b01-2a4769c84680
[Info : FFT] Successfully retrieved ParticleSystem for VentValve.
[Info : FFT] Module_VentValve has started.
[Error : FFT] VFXASLCurve is null.```
@surreal loom , I'm not sure from your code what you're exactly trying to do and what you have before the code you sent. It looks like you're trying to get data from Micro Engineer?
In any case, you can fetch the data yourself. First you need to get the activevessel like so:
ActiveVessel = GameManager.Instance?.Game?.ViewController?.GetActiveVehicle(true)?.GetSimVessel(true); (there's probably a SpaceWarp API for that too, haven't checked)
Then, altitude above ground is:
ActiveVessel.AltitudeFromScenery
Above sea level is:
ActiveVessel.AltitudeFromSeaLevel
Both values should be != null if you have an active vessel (you're in flight).
so this is my new code and what I've been attempting to do. it's uploaded on https://github.com/cvusmo/FFT/tree/dev/FFTProject
But the idea is I have my module, data, and partcomponentmodule which make a module in unity that allows me to set an animationcurve. then i simply create a way to get the information I need, add it to the onmodulefixedupdate and it updates accordingly
Ok. If you want to get the altitude you don't need the entire Utility class I linked you, just the line that the link pointed to (Utility.cs#L33)
So you need:
var activeVessel = GameManager.Instance?.Game?.ViewController?.GetActiveVehicle(true)?.GetSimVessel(true);
var altitudeAgl = activeVessel.AltitudeFromScenery;```
You got null probably because you didn't initialize activeVessel before fetching the altitude
do you have debugging set up? it's invaluable for hunting null refs 🙂
oh i have i just couldnt figure out why it was returning null
it pointed to it but i was confused as to why it was "working" but it wasn't working
and why i was getting null values
so i thought it was the altitude not working, not the activevessel
so I've broken all the classes into a structure like this:
public class AltitudeFromScenery
{
public double altitudeFromScenery { get; private set; }
public void RefreshData(VesselComponent vessel)
{
altitudeFromScenery = vessel.AltitudeFromTerrain;
}
}```
that way I can remove Utility and simplify things a bit
exactly 👍
sweet. glad im slowly figuring out how things work and better practices. thanks for the help on this i cant believe i didnt see it earlier lol
all good, glad you're progressing!
slowly but surely! the goal is each mod to get better at it
public override void OnModuleFixedUpdate(float fixedDeltaTime)
{
base.OnModuleFixedUpdate(fixedDeltaTime);
var activeVessel = GameManager.Instance?.Game?.ViewController?.GetActiveVehicle(true)?.GetSimVessel(true);
if (activeVessel == null) return;
_refreshVesselData.activeVessel = activeVessel;
_refreshVesselData.altitudeAgl.RefreshData(activeVessel);
_refreshVesselData.altitudeAsl.RefreshData(activeVessel);
ASLValve = (float)_refreshVesselData.altitudeAsl.altitudeAsl;
AGLValve = (float)_refreshVesselData.altitudeAgl.altitudeAgl;
float aslCurve = DataVentValve.VFXASLCurve.Evaluate(ASLValve);
float aglCurve = DataVentValve.VFXAGLCurve.Evaluate(AGLValve);
Animator.SetFloat("ASLValve", aslCurve);
Animator.SetFloat("AGLValve", aglCurve);
if (IsActive)
{
if (ASLValve > 1000 || AGLValve > 1000)
{
StartVFX();
}
else if (ASLValve > 0 || AGLValve > 0)
{
StopVFX();
}
}
}```
@south girder still didn't do it correctly. hm
so what's wrong? Do you get something for activeVessel?
oh and use AltitudeFromScenery instead of AltitudeFromTerrain. I know it's counter-intuitive, but I've found that the correct value is the first one, while I'm not sure what the other value represents...
Weird. I'll make those changes and get a debug log for active vessel
I have been using ALtitudeFromScenery. I saw your note on it and it is counterintuitive.
public class AltitudeAgl
{
public double altitudeAgl { get; private set; }
public void RefreshData(VesselComponent vessel)
{
altitudeAgl = vessel.AltitudeFromScenery;
}
}
@south girder got it working. thanks for the help! now ive gotta tweak things in unity and itll work how i want!
[Info : FFT] OnModuleFixedUpdate has started.
[Info : FFT] StartVFX Confirmed.
[Info : FFT] StopVFX Confirmed.
Now to get the animation to play now that the code is working
altitudeSeaLevel = (float)refreshVesselData.altitudeAsl.altitudeAsl;
float normalizedASL = altitudeSeaLevel / maxASL;
normalizedASL = Mathf.Clamp(normalizedASL, 0, 1);
float ASLFromCurve = DataVentValve.VFXASLCurve.Evaluate((float)normalizedASL);
Animator.SetFloat("ASL", ASLFromCurve);```
@south girder does this look correct?
Sure, it looks alright
I keep getting this:
at FFT.Modules.Module_VentValve.OnModuleFixedUpdate (System.Single fixedDeltaTime) [0x0002d] in C:\Users\nicho\source\repos\FFT\FFTProject\Modules\Module_VentValve.cs:96
at KSP.Sim.Definitions.PartBehaviourModule.OnFixedUpdate (System.Single deltaTime) [0x00069] in <57799b60a4cd4df8b3c9aec811d65aed>:0
at KSP.Game.GameInstance.FixedUpdate () [0x000b1] in <57799b60a4cd4df8b3c9aec811d65aed>:0 ```
line 96 is: float ASLFromCurve = DataVentValve.VFXASLCurve.Evaluate((float)normalizedASL);
do you have debugging set? And by that I mean did you set up your environment by following this guide: https://gist.github.com/gotmachine/d973adcb9ae413386291170fa346d043.
You can set a breakpoint at line 96 and see what exactly is null at that point. Maybe DataVentValve, maybe VFXASLCurve.
I have not done that. Def will set this up to debug further. I appreciate that!
Nice! But shouldn’t that trail off horizontally in the breeze? Not that there’s ever been much breeze at KSC. Seems like it’s dead calm there all the time
Its got dynamic gravity turned on so it responds to wind. just no wind. curious how i could turn the wind up. ive also got more dynamic settings to add but first is getting it to work properly.
issues:
- switching assembly name to com.github.cvusmo.fancyfueltanks has now
[ERR 02:09:39.985] [Serialization] Error converting value "FFT.Modules.Module_TriggerVFX, FFT, Version=0.1.3.0, Culture=neutral, PublicKeyToken=null" to type 'System.Type'. Path 'Vessels[0].parts[16].PartModulesState[4].ModuleData[0].ModuleType', line 7404, position 123
- the altitude check i've added isn't working. it triggers the animation properly but it isnt calculating altitude and telling the animation to turn on or off.
"dynamic gravity", "wind"... am I playing a different game than you? 😆
For wind?
pending gotta find em
im watching a streamer play baldur's gate 3 and i just woke up
DynamicGravityForVFX and TriggerVFXFromAnimation
I use TriggerVFXFromAnimation to trigger my animations on/off since it's a super simple script to use
DynamicGravityForVFX
By "wind", do you mean atmospheric drag?
its going to use that eventually
as far as wind, i haven tfound anything
but trying to update the mod to work with the new naming changes etc has broken the mod. it doesnt deserialize correctly and i have zero experience with serialization/deserialization so last night i was trying to figure that out
No idea what that error represents, sorry
whats weird is that the animation plays but for some reason my altitude isnt being calculated
so that i havnet figured out, but i can get the animation to play
not sure where I messed up in my onmodulefixedupdate
i fixed the first issue so the mod loads now
now its figuring out how to get the altitude to update properly
if (FFTPlugin.Instance._state == GameState.Launchpad && altitudeSeaLevel < 1000 && ASLFromCurve > 0)
{
StartVFX();
}
else if (altitudeSeaLevel >= 1000 || ASLFromCurve <= 0)
{
StopVFX();
}```
I think this logic will now work. I wasn't including anything in the logic about altitude so that's why it wasn't using altitude to stop or start
@south girder found wind!
thats planetary level so no idea how vessels interact with it etc
fingers crossed might have fixed it
I’m pretty sure you broke wind…
interesting!
This is very cool! Though, I suspect any real rocket would generally switch this off as soon as they launch. The vapor vents are, as you pointed out in your excellent video, releasing pressure so the thing doesn't burst or rupture while it's on the pad as the cryogenic propellants warm up. As soon as you start the motor its high speed turbo pumps are doing their absolute best to empty the tanks for you just as fast as they can. That should take care of any pressure issues on the stage that's lit. Perhaps this sort of venting might still occur on an upper stage, though I've never seen it visibly so. Presumably the high velocity airstream carries it away too quickly to see it like a cloud.
Not sure. I've gotta ask Lara about it and a few rocket friends of mine.
For game purposes I didn't want it to just disappear so testing it at 1000m. Eventually I'm going to have it scale off multiple factors to give it a more realistic feel
But it also needs a purpose in the game. It's purpose is a convector. It helps keep the tanks cool. But very limited.
Tank has to be 90% or more on fuel and below 1000m right now. 🤔
There is two pressures in the game. Not sure how they work but getting one dynamic system functional and adding more. Really need 1.4 to drop and give us reentry heating
@fierce sundial how do I smooth this out better and get rid of the shadowed faces/edges?
right click > shade auto smooth
jf you dont have that go shade smooth, then to the mesh information tab (green triangle with square corners). there will be. a normals drop down i think, click it and enable auto smooth
Yup knew that. Just wanted to see how to make it cleaner. I've worked on adding sharp areas to make it look cleaner and not have a weird angle
Concept art I'm using to make the new hydrogen Tanks for nuclear engines
Nice!
thanks. im really enjoying it. modelling/texturing arent too hard. the programming just takes a lot of time to get things to function how i want them to
they're also 20T of hydrogen. the big giant ball is 50T.
not sure if this is a bit overkill but i like it
What's the top cylindrical part? Is that a separate tank of part of the torroidal tank below?
I assume it's a torroid inside some sort of housing...
?
the top cylindrical part is supposed to connect things so that it actually gets fuel
dont know what the technical name of it is
Probably from a line of Torrid Toroids or some such..
but using the same artistic style for all hydrogen tanks
so they use this
not sure if i want it to be a single metal piece or detail it to be like its bolted together
Ahhh, that bit! I was referring to the cylindrical green and blue part above it. That gray thing would be idunno a stage interconnect ring or some such?
Stage interconnect sounds about right. Or stage adapter