Пример #1
0
        public static Vcf ParseVcf(string filename)
        {
            var vcf = new Vcf();

            using (var br = new Bwd2Reader(filename))
            {
                br.FindNext("VCFC");

                vcf.VariantName             = br.ReadCString(16);
                vcf.VdfFilename             = br.ReadCString(13);
                vcf.VtfFilename             = br.ReadCString(13);
                vcf.EngineType              = br.ReadUInt32();
                vcf.SuspensionType          = br.ReadUInt32();
                vcf.BrakesType              = br.ReadUInt32();
                vcf.WdfFrontFilename        = br.ReadCString(13);
                vcf.WdfMidFilename          = br.ReadCString(13);
                vcf.WdfBackFilename         = br.ReadCString(13);
                vcf.ArmorFront              = br.ReadUInt32();
                vcf.ArmorLeft               = br.ReadUInt32();
                vcf.ArmorRight              = br.ReadUInt32();
                vcf.ArmorRear               = br.ReadUInt32();
                vcf.ChassisFront            = br.ReadUInt32();
                vcf.ChassisLeft             = br.ReadUInt32();
                vcf.ChassisRight            = br.ReadUInt32();
                vcf.ChassisRear             = br.ReadUInt32();
                vcf.ArmorOrChassisLeftToAdd = br.ReadUInt32();

                br.FindNext("WEPN");
                vcf.Weapons = new List <VcfWeapon>();
                while (br.Current != null && br.Current.Name != "EXIT")
                {
                    var vcfWeapon = new VcfWeapon
                    {
                        MountPoint  = (MountPoint)br.ReadUInt32(),
                        GdfFilename = br.ReadCString(13)
                    };
                    vcf.Weapons.Add(vcfWeapon);
                    br.Next();
                }
            }

            if (vcf.WdfFrontFilename.ToUpper() != "NULL")
            {
                vcf.FrontWheelDef = WdfParser.ParseWdf(vcf.WdfFrontFilename);
            }
            if (vcf.WdfMidFilename.ToUpper() != "NULL")
            {
                vcf.MidWheelDef = WdfParser.ParseWdf(vcf.WdfMidFilename);
            }
            if (vcf.WdfBackFilename.ToUpper() != "NULL")
            {
                vcf.BackWheelDef = WdfParser.ParseWdf(vcf.WdfBackFilename);
            }

            return(vcf);
        }
Пример #2
0
        public GameObject ImportVcf(string filename, bool importFirstPerson, out Vdf vdf)
        {
            Vcf vcf = VcfParser.ParseVcf(filename);

            vdf = VdfParser.ParseVdf(vcf.VdfFilename);
            Vtf vtf = VtfParser.ParseVtf(vcf.VtfFilename);

            Car carObject = Object.Instantiate(_carPrefab);

            carObject.Configure(vdf, vcf);
            carObject.gameObject.name = vdf.Name + " (" + vcf.VariantName + ")";

            foreach (VLoc vLoc in vdf.VLocs)
            {
                GameObject vlocGo = new GameObject("VLOC");
                vlocGo.transform.parent        = carObject.transform;
                vlocGo.transform.localRotation = Quaternion.LookRotation(vLoc.Forward, vLoc.Up);
                vlocGo.transform.localPosition = vLoc.Position;
            }

            GameObject chassis = new GameObject("Chassis");

            chassis.transform.parent = carObject.transform;

            GameObject thirdPerson = new GameObject("ThirdPerson");

            thirdPerson.transform.parent = chassis.transform;

            Transform[] weaponMountTransforms = new Transform[vdf.HLocs.Count];
            for (int i = 0; i < vdf.HLocs.Count; ++i)
            {
                HLoc      hloc       = vdf.HLocs[i];
                Transform mountPoint = new GameObject(hloc.Label).transform;
                mountPoint.parent        = thirdPerson.transform;
                mountPoint.localRotation = Quaternion.LookRotation(hloc.Forward, hloc.Up);
                mountPoint.localPosition = hloc.Position;
                weaponMountTransforms[i] = mountPoint;
            }

            Dictionary <string, GameObject> partDict = new Dictionary <string, GameObject>();

            for (int i = 0; i < vdf.PartsThirdPerson.Count; ++i)
            {
                GameObject healthObject = new GameObject("Health " + i);
                healthObject.transform.SetParent(thirdPerson.transform);
                ImportCarParts(partDict, healthObject, vtf, vdf.PartsThirdPerson[i], _noColliderPrefab, false, false, i);
                if (i != 0)
                {
                    healthObject.SetActive(false);
                }
            }

            MeshFilter[] meshFilters = thirdPerson.GetComponentsInChildren <MeshFilter>();
            Bounds       bounds      = new Bounds();

            bounds.SetMinMax(Vector3.one * float.MaxValue, Vector3.one * float.MinValue);
            foreach (MeshFilter meshFilter in meshFilters)
            {
                Vector3 min = Vector3.Min(bounds.min, meshFilter.transform.position + meshFilter.sharedMesh.bounds.min) - thirdPerson.transform.position;
                Vector3 max = Vector3.Max(bounds.max, meshFilter.transform.position + meshFilter.sharedMesh.bounds.max) - thirdPerson.transform.position;
                bounds.SetMinMax(min, max);
            }

            GameObject chassisCollider = new GameObject("ChassisColliders");

            chassisCollider.transform.parent = carObject.transform;
            ImportCarParts(partDict, chassisCollider, vtf, vdf.PartsThirdPerson[0], _carBodyPrefab, true);

            for (int i = 0; i < vcf.Weapons.Count; ++i)
            {
                VcfWeapon weapon     = vcf.Weapons[i];
                int       mountPoint = weapon.MountPoint;
                HLoc      hloc       = vdf.HLocs[mountPoint];
                weapon.RearFacing = hloc.FacingDirection == 2;

                SdfPart[] partsArray;
                switch (hloc.MeshType)
                {
                case HardpointMeshType.Top:
                    partsArray = weapon.Gdf.TopParts;
                    break;

                case HardpointMeshType.Side:
                    partsArray = weapon.Gdf.SideParts;
                    break;

                case HardpointMeshType.Inside:
                    partsArray = weapon.Gdf.InsideParts;
                    break;

                case HardpointMeshType.Turret:
                    partsArray = weapon.Gdf.TurretParts;
                    break;

                default:
                    partsArray = null;
                    break;
                }

                if (partsArray != null)
                {
                    Transform weaponTransform = new GameObject(weapon.Gdf.Name).transform;
                    weaponTransform.SetParent(weaponMountTransforms[i]);
                    weaponTransform.localPosition = Vector3.zero;
                    weaponTransform.localRotation = Quaternion.identity;
                    ImportCarParts(partDict, weaponTransform.gameObject, vtf, partsArray, _noColliderPrefab, false);
                    weapon.Transform = weaponTransform;

                    // Disable depth test for 'inside' weapons, otherwise they are obscured.
                    if (hloc.MeshType == HardpointMeshType.Inside)
                    {
                        MeshRenderer weaponRenderer = weaponTransform.GetComponentInChildren <MeshRenderer>();
                        if (weaponRenderer != null)
                        {
                            weaponRenderer.sharedMaterial.shader = Shader.Find("Custom/CutOutWithoutZ");
                        }
                    }
                }
                else
                {
                    weapon.Transform = chassis.transform;
                }
            }

            // Note: The following is probably how I76 does collision detection. Two large boxes that encapsulate the entire vehicle.
            // Right now this won't work with Open76's raycast suspension, so I'm leaving this off for now. Investigate in the future.
            //var innerBox = chassisCollider.AddComponent<BoxCollider>();
            //innerBox.center = vdf.BoundsInner.center;
            //innerBox.size = vdf.BoundsInner.size;

            //var outerBox = chassisCollider.AddComponent<BoxCollider>();
            //outerBox.center = vdf.BoundsOuter.center;
            //outerBox.size = vdf.BoundsOuter.size;

            RaySusp[] frontWheels = null;
            if (vcf.FrontWheelDef != null)
            {
                frontWheels = CreateWheelPair(partDict, "Front", 0, carObject.gameObject, vdf, vtf, vcf.FrontWheelDef);
                carObject.Movement.FrontWheels = frontWheels;
            }
            if (vcf.MidWheelDef != null)
            {
                CreateWheelPair(partDict, "Mid", 2, carObject.gameObject, vdf, vtf, vcf.MidWheelDef);
            }

            RaySusp[] rearWheels = null;
            if (vcf.BackWheelDef != null)
            {
                rearWheels = CreateWheelPair(partDict, "Back", 4, carObject.gameObject, vdf, vtf, vcf.BackWheelDef);
                carObject.Movement.RearWheels = rearWheels;
            }

            if (importFirstPerson)
            {
                GameObject firstPerson = new GameObject("FirstPerson");
                firstPerson.transform.parent = chassis.transform;
                ImportCarParts(partDict, firstPerson, vtf, vdf.PartsFirstPerson, _noColliderPrefab, false, true, 0, LayerMask.NameToLayer("FirstPerson"));

                carObject.InitPanels();
                firstPerson.SetActive(false);
            }

            carObject.Movement.Initialise(chassis.transform, frontWheels, rearWheels);

            return(carObject.gameObject);
        }