EvilKot
Members-
Posts
17 -
Joined
-
Last visited
Content Type
Profiles
Forums
Developer Articles
KSP2 Release Notes
Everything posted by EvilKot
-
Determine collision at point
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
At this moment i'll use temporary solution - simply force to sleep all Rigidbodys: Rigidbody[] rbs = (Rigidbody[])FindObjectsOfType(typeof(Rigidbody)); and OnFixedUpdate() : foreach (var rb in rbs) { rb.Sleep(); } This completely disables physics and collisions, so it may be helpful to anyone who looking for this. I just not sure if this is a best way... ---------- Finally slove this problem, so how to "Determine collision at point": CelestialBody.pqsController.GetSurfaceHeight(Vector3d radialVector) gives us a terrain altitude at some point. According to mechJeb & HyperEdit: Vector3d radialVector = ( QuaternionD.AngleAxis(Longitude, Vector3d.down) * QuaternionD.AngleAxis(Latitude, Vector3d.forward) * Vector3d.right), where: double Longitude = vessel.mainBody.GetLongitude(point); double Latitude = vessel.mainBody.GetLatitude(point); and: Vector3d point - some coords in world coord system. Finally: Vector3d point; //coords (vessel or anything else) double Longitude = vessel.mainBody.GetLongitude(point); double Latitude = vessel.mainBody.GetLatitude(point); double srfHeight = vessel.mainBody.pqsController.GetSurfaceHeight( QuaternionD.AngleAxis(Longitude, Vector3d.down) * QuaternionD.AngleAxis(Latitude, Vector3d.forward) * Vector3d.right) - vessel.mainBody.pqsController.radius; //surface height, shows negative values if under sea level double alt = (Vector3d.Distance(vessel.mainBody.transform.position, point) - vessel.mainBody.Radius); //altitude, shows negative values if under sea level too and if srfHeight > alt anything located on "point" will explode. Just note that pqsController of Sun = null! -
Determine collision at point
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
Thank you, but if i understood you right this solution will be equals to "stop warp if vessel below constant altitude at sea level". I can just increase "sphere" where warp stops like: vessel.mainBody.Radius + 10000, so warp will brake under 10km (altitude at sea level). And are you shure that time warp works simmilar to your answer? I see in documentation that every CelestialBodiy object has their own set of altitude limits for maximum time warp multiper. This is not actually i'm looking for. For example - i wanna warp from KSC's runway to the Mun which is behind those mountains on the west side, so minimum warp altitude at KSC will be ~100 meters and in mountains it should be several thousands. I can't set constant "x" for all planet. -
Hello. I'm developing a warp drive mod (thousands of them! ) The general idea based on teleporting vessel very very very fast (once per frame) using vessel.SetPosition(Vector3d position) method which makes illusion that ship is really flying whenever you need. Everything works great expect of "through planet warp" and i asking you for help. I have serious language(english) problems and i suck at explaining things (Just wanna say sorry). As i said i'm teleporting vessel every frame in target direction: jumpToPos = vessel.transform.position + (TS.TargetVector * destination); //jumpToPos, TargetVector are Vector3d variables, destination is increases and decreases. then: vessel.SetPosition(jumpToPos); but if new vessel position will be under surface vessel will explode (ORLY? ) so i have to check jumpToPos before jumping on it. i can simple determine collision: (x-a)^2 + (y-^2 + (z-c)^2 Mustn't be less or equals to R^2, where a, b, c, R - planet position and radius and x, y, z are jumpToPos values. or: (Math.Pow((jumpToPos.x - vessel.mainBody.transform.position.x), 2) + Math.Pow((jumpToPos.y - vessel.mainBody.transform.position.y), 2) + Math.Pow((jumpToPos.z - vessel.mainBody.transform.position.z), 2)) <= Math.Pow(vessel.mainBody.Radius, 2) So if this condition returns true i shouldn't jump because of explosion. But this thing work only if planet is a perfect sphere without mountains, hils and etc (nothing above sea level) so i have a second check using raycast: if (Physics.Raycast(jumpToPos, TS.TargetVector, out headHit, (float)(destination), 1 << 15)) and if this condition is true i shouldn't jump too. Now everything is simple: every frame i'm calculate jumpToPos and when it's safe to jump on i'm jumping on it, if not(planet collision) i'm just standing and waiting when jumpToPos will became safe again (flew from planet) here's example (Mad skillz included): where jumpToPos is A, then B, thec C.... When the vessel is at point C, next jumpToPos will be D and the raycast with length CD will say vessel to keep on C. On the next step raycast from D to E won't find collision but E belongs to sphere and the vessel will keep on C too. Same for the F point. At the end vessel will jump to G and everything will be ok. Just show a dark screen while vessel is holding on C Zoomed: But!!! if more than one jumpToPos points will be below surface but above sea level there's will be a problem: step 1: vessel on A, jumpToPos = B, B is safe(no collision) => jumping to B step 2: vessel on B, jumpToPos = C, C isn't safe(raycast detected hit), keep vessel on B step 3: vessel on B, JumpToPos = D, D is safe! No raycast hit, not belongs to sphere(red area), jumping to D and exploding! So i need a 3rd check: if(lastColAlt>vessel.altitude) { isSafeToJump = false; } where lastColAlt = FlightGlobals.getAltitudeAtPos(headHit.barycentricCoordinate); //from last raycast hit with surface to determine if the vessel is under surface Full code: private void Jump(double destination) { bool isSafeToJump = true; if (Physics.Raycast(jumpToPos, TS.TargetVector, out headHit, (float)(destination + 50.0), 1 << 15)) //is any collision on the way to next jump point. Do it before calculating new jumpToPos value { lastColAlt = FlightGlobals.getAltitudeAtPos(headHit.barycentricCoordinate); isSafeToJump = false; } if (lastColAlt > vessel.altitude) // if under surface { isSafeToJump = false; } jumpToPos = vessel.transform.position + (TS.TargetVector * destination); // calculate next jump point if ((Math.Pow((jumpToPos.x - vessel.mainBody.transform.position.x), 2) + Math.Pow((jumpToPos.y - vessel.mainBody.transform.position.y), 2) + Math.Pow((jumpToPos.z - vessel.mainBody.transform.position.z), 2)) <= Math.Pow(vessel.mainBody.Radius + 5, 2)) // is next jump point belongs to planet(sphere only) { isSafeToJump = false; lastColAlt = 0.0; //drop value } ///Jump or not if(isSafeToJump) { lastSafePos = vessel.transform.position; lastColAlt = 0.0; vessel.SetPosition(jumpToPos); } else { vessel.SetPosition(lastSafePos); print("ABORT!"); } Now i have brilliant monkey code which works every 2nd time. So... Is there any way to check collision at point (like i can check altitude FlightGlobals.getAltitudeAtPos())? Or any ideas?! Or how can i disable collision at all? vessel.GoOnRails() can't solve this problem. vessel.collider retutrns null ref exception, looping from every part of the vessel and disabling collider has no effect, Physics.IgnoreCollision - nothing too. Thank you for your answers! P.S. bounus-proof of concept: Laythe: Warping to Ike:
-
Mod directory question
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
Thank you guys! Also does anyone know how to disable ground collisions on active vessel? Physics.IgnoreCollision has no effect and vessel.collider returns null reference exception -
Is it necessary to create mod which located in GameData folder or can i locate it in Parts & Plugins folders?
-
Transporting:
-
vessel.SetPosition() issue :)
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
SetPosition is the only func i can use for my "mod", i'll try to find more accurate position. -
vessel.SetPosition() issue :)
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
Thank you, i'll look for another way -
vessel.SetPosition() issue :)
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
Ah, solution always come after posting: public override void OnFixedUpdate() { base.OnFixedUpdate(); bug += vessel.GetWorldPos3D().magnitude - prevPos.magnitude; vessel.SetPosition(vessel.GetWorldPos3D() + (vessel.transform.up*(float)bug)); prevPos = vessel.GetWorldPos3D(); } this works, but only in surface. In orbit this is laggy as hell. -
Greetings. Just wanna say sorry for my english, i hope you'll understand my question from code i posted below... I've found a bug and looking for help to overcome it: vessel.SetPosition(vessel.GetWorldPos3D()); sets the vessel a little bit behid from previous position. For example i want my vessel to stay in current position: public override void OnFixedUpdate() { base.OnFixedUpdate(); vessel.SetPosition(vessel.GetWorldPos3D()); } but it starts flying backwards ( in vessel.transform.down direction) lol This is my attempt to catch delta bug: public override void OnFixedUpdate() { base.OnFixedUpdate(); bug = Vector3d.Distance(vessel.GetWorldPos3D(), prevPos); //here is it! vessel.SetPosition(vessel.GetWorldPos3D(); //+ (vessel.transform.up * bug)); this will work every secon'd time prevPos = vessel.GetWorldPos3D(); } The interesting thing is that "bug" is changing with speed, ship mass, and direction. Any ideas?
-
Hello. I'm looking for solution to control retractable parts from a plugin. For example: If your surface velocity reaches 10m/s, panels retracts to avoid breaking. Unfortunately I'm stuck at this point: PartModule[] parts = (FindObjectsOfType(typeof(PartModule)) as PartModule[]); foreach(PartModule p in parts) { if(p.vessel == FlightGlobals.ActiveVessel) { if (p.ClassName == "ModuleDeployableSolarPanel") { //p.part.SendEvent(" whichEvent? ") // } } } Thank you!
-
looking for coordinates of the planets
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
Yes, exactly! I made an unaccurate example with GetSrfVelocity(sorry) because i was looking for vector3d; Thank you a lot! -
Playing custom sound when button is clicked
EvilKot replied to EvilKot's topic in KSP1 C# Plugin Development Help and Support
Can't belive, but i found a solution: WWW url = new WWW("file://" + "C:/....../Parts/TestPart/Sound/sound1.wav"); // or simply use KSPUtil.ApplicationRootPath to get ksp directory audio.clip = url.audioClip; while (!audio.clip.isReadyToPlay) { } audio.PlayOneShot(url.audioClip); It may be helpful! -
Greetings! First of all i'm going to say sorry for my english, but i hope you'll undersand my question. I have read some tutorials and tried to make an own small plugin mod. I've created a module, which calls a GUI window with a button. The OnClick() method cals even a button is pressed. So now i'm trying to play custom sound in this meth. Could you answer me where should i locate my audio file (for example - mysound.wav)? Should it be in the module folder like a KSP/Parts/MyPart/Sounds/mysound.wav or in game recources KSP/GameData/Squad/Sounds. What should i use to load it and play(WWW class with url linked to audio file) or Recources.Load() method)? Should i create a new game object, wait when audio.clip.isReadyToPlay equals true and etc? I've watched lots of posts and there are so many different ways to realise that, but nothing works. I am grateful for any help. Thanks!