Усовершенствованный Minecraft v2.0 на Unity3d

Урок по инициативе Andrey . Теперь все блоки в игре сохраняются/загружаются. Ура!



А код под катом…


Файл MineCraftController.cs:

/*
Author: afrokick
Forum: www.devby.ru
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MineCraftController : MonoBehaviour
{

    public GameObject block;
    public Material mat_blue;
    public Material mat_red;

    // Use this for initialization
    void Start()
    {
        LoadBlocks();//new
        block.renderer.sharedMaterial = mat_blue;//new
        Screen.showCursor = false;
    }

    // Update is called once per frame
    void Update()
    {
        Ray ray = Camera.mainCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, 5f) && hit.collider.CompareTag("Block"))
        {
            if (Input.GetMouseButtonUp(0))
            {
                Vector3 pos = hit.collider.transform.position;
                pos += hit.normal;

                Instantiate(block, pos, Quaternion.identity);
            }
            else if (Input.GetMouseButtonUp(1))
            {
                DestroyObject(hit.collider.gameObject);
            }
        }
        else if (Physics.Raycast(ray, out hit, 5f) && hit.collider.name.Equals("Plane"))
        {
            if (Input.GetMouseButtonUp(0))
            {
                Vector3 pos = hit.point;
                pos.y = 0;
                pos.x = Mathf.Round(pos.x);
                pos.z = Mathf.Round(pos.z);

                Instantiate(block, pos, Quaternion.identity);
            }
        }
    }

    void OnGUI()
    {
        if (Input.GetKey(KeyCode.M))
        {
            Screen.showCursor = true;

            GUILayout.BeginVertical();
            GUILayout.Label(block.renderer.sharedMaterial.name + "");

            if (GUILayout.Button("Blue"))
            {
                block.renderer.sharedMaterial = mat_blue;
            }
            if (GUILayout.Button("Red"))
            {
                block.renderer.sharedMaterial = mat_red;
            }
            GUILayout.EndVertical();
        }
        else
        {
            Screen.showCursor = false;
        }
    }

    void OnApplicationQuit()
    {
        SaveBlocks();
    }
    /// <summary>
    /// Для загрузки блоков
    /// </summary>
    void LoadBlocks()
    {
        //если нету записи, то выходим
        if (!PlayerPrefs.HasKey("blocks"))
            return;
        //получаем строку, содержащую все блоки
        string strBlocks = PlayerPrefs.GetString("blocks");
        //получаем массив блоков
        string[] masBlocks = strBlocks.Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);
        //перебираем каждый блок
        foreach (string s in masBlocks)
        {
            //Массив параметров блока
            string[] masParam = s.Split(new char[] { '#' }, System.StringSplitOptions.RemoveEmptyEntries);
            //Позиция
            Vector3 pos = new Vector3(float.Parse(masParam[0]), float.Parse(masParam[1]), float.Parse(masParam[2]));
            //Тип материала
            byte matType = byte.Parse(masParam[3]);
            block.renderer.sharedMaterial = GetMatById(matType);
            //Добавляем блок на сцену
            Instantiate(block, pos, Quaternion.identity);
        }

        Debug.Log(string.Format("Загружено {0} блоков!", masBlocks.Length));
    }
    /// <summary>
    /// Для сохранения блоков
    /// </summary>
    void SaveBlocks()
    {
        //получаем все блоки на сцене
        GameObject[] allBlocks = GameObject.FindGameObjectsWithTag("Block");
        string saveStr = "";
        //берем каждый блок
        foreach (GameObject g in allBlocks)
        {
            //позиция блока
            Vector3 pos = g.transform.position;
            //записываем информацию о блоке в строку.
            saveStr += string.Format("{0}#{1}#{2}#{3};", pos.x, pos.y, pos.z, GetIdByMat(g.renderer.sharedMaterial));
        }
        //добавляем строку с блоками в хронилище
        PlayerPrefs.SetString("blocks", saveStr);
        //сохраняем!!!
        PlayerPrefs.Save();

        Debug.Log(string.Format("Сохранено {0} блоков", allBlocks.Length));
    }
    /// <summary>
    /// Возвращает ИД указанного материала
    /// </summary>
    /// <param name="m"></param>
    /// <returns></returns>
    byte GetIdByMat(Material m){
        switch (m.name)
        {
            case "mBlue":
                return 0;
            case "mRed":
                return 1;
            default:
                return 0;
        }
    }
    /// <summary>
    /// Возвращает Материал по ИД
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    Material GetMatById(byte id)
    {
        switch (id)
        {
            case 0:
                return mat_blue;
            case 1:
                return mat_red;
            default:
                return mat_blue;
        }
    }
}

43 комментария

avatar
блин, а мне ошибку прописывает
avatar
если невидно, там написано: _Scripts/MineCraftController.cs(129,21): error CS0117: `UnityEngine.PlayerPrefs' does not contain a definition for `Save'
avatar
Напиши PlayerPrefs, поставь "." и посмотри, есть ли в списке методов метод с таким именем?
avatar
эх, всё равно пишет ошибку((
avatar
Код полностью идентичный моему?
avatar
ПОЛНОСТЬЮ, может пакейдж тогда кинешь? Или у меня просто на просто версия не та?
avatar
Так а вообще класс такой есть PlayerPrefs? Методы в нем есть какие-нибудь?
avatar
Изменил размеры куба, получилась стена. Но при создании, стены накладываются друг на друга. Скажите пожалуйста, как это можно исправить?
avatar
Дело в том, что объекты должны быть размерами 1х1х1, либо 2х2х2 и т.д.
avatar
UnityException: Tag: Block is not defined!
ArtisanControler.SaveBlocks () (at Assets/_Sripts/ArtisanControler.cs:116)
ArtisanControler.OnApplicationQuit () (at Assets/_Sripts/ArtisanControler.cs:80)
Выдало такую ошибку.Что делеть, объясните плиз как решить эту проблему?
avatar
Просмотрите еще раз видео, где-то в начале мы назначаем тег Block — вы этого не сделали.
avatar
Привет, помогите пожалуйста, объесните как работать в этом скрипте- что и куда нужно вписать что бы я мог увиличивать количество блоков? Как ставить русское название блока в скрипте? а то я поставил а там какието каракули. ПОМОГИТЕ ПОЖАЛУЙСТА
avatar
Добавить в начало скрипта переменную для материала нового
public Material new_mat;


Отобразить кнопку в OnGUI
if (GUILayout.Button("Новый материал"))
            {
                block.renderer.sharedMaterial = new_mat;
            }


Добавить в методы GetIdByMat
case "mNew":
                return 2;

где mNew — это имя нового материала внутри юнити
2 — следующий ид, т.е. с каждый новым материалом он увеличивается на +1

и в метод GetMatById(byte id)
case 2:
                return new_mat;
avatar
Я не чего не понял, поменяйте пожалуйста сами и киньт мне готовый скрипит, пожалуйста
avatar
/*
Author: afrokick
Forum: www.blog.devby.ru
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MineCraftController : MonoBehaviour
{

    public GameObject block;
    public Material mat_blue;
    public Material mat_red;
    public Material new_mat;//тут добавили новую переменную

    // Use this for initialization
    void Start()
    {
        LoadBlocks();//new
        block.renderer.sharedMaterial = mat_blue;//new
        Screen.showCursor = false;
    }

    // Update is called once per frame
    void Update()
    {
        Ray ray = Camera.mainCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, 5f) && hit.collider.CompareTag("Block"))
        {
            if (Input.GetMouseButtonUp(0))
            {
                Vector3 pos = hit.collider.transform.position;
                pos += hit.normal;

                Instantiate(block, pos, Quaternion.identity);
            }
            else if (Input.GetMouseButtonUp(1))
            {
                DestroyObject(hit.collider.gameObject);
            }
        }
        else if (Physics.Raycast(ray, out hit, 5f) && hit.collider.name.Equals("Plane"))
        {
            if (Input.GetMouseButtonUp(0))
            {
                Vector3 pos = hit.point;
                pos.y = 0;
                pos.x = Mathf.Round(pos.x);
                pos.z = Mathf.Round(pos.z);

                Instantiate(block, pos, Quaternion.identity);
            }
        }
    }

    void OnGUI()
    {
        if (Input.GetKey(KeyCode.M))
        {
            Screen.showCursor = true;

            GUILayout.BeginVertical();
            GUILayout.Label(block.renderer.sharedMaterial.name + "");

            if (GUILayout.Button("Blue"))
            {
                block.renderer.sharedMaterial = mat_blue;
            }
            if (GUILayout.Button("Red"))
            {
                block.renderer.sharedMaterial = mat_red;
            }
            if (GUILayout.Button("Новый материал"))//отобразили кнопку
            {
                block.renderer.sharedMaterial = new_mat;
            }
            GUILayout.EndVertical();
        }
        else
        {
            Screen.showCursor = false;
        }
    }

    void OnApplicationQuit()
    {
        SaveBlocks();
    }
    /// <summary>
    /// Для загрузки блоков
    /// </summary>
    void LoadBlocks()
    {
        //если нету записи, то выходим
        if (!PlayerPrefs.HasKey("blocks"))
            return;
        //получаем строку, содержащую все блоки
        string strBlocks = PlayerPrefs.GetString("blocks");
        //получаем массив блоков
        string[] masBlocks = strBlocks.Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);
        //перебираем каждый блок
        foreach (string s in masBlocks)
        {
            //Массив параметров блока
            string[] masParam = s.Split(new char[] { '#' }, System.StringSplitOptions.RemoveEmptyEntries);
            //Позиция
            Vector3 pos = new Vector3(float.Parse(masParam[0]), float.Parse(masParam[1]), float.Parse(masParam[2]));
            //Тип материала
            byte matType = byte.Parse(masParam[3]);
            block.renderer.sharedMaterial = GetMatById(matType);
            //Добавляем блок на сцену
            Instantiate(block, pos, Quaternion.identity);
        }

        Debug.Log(string.Format("Загружено {0} блоков!", masBlocks.Length));
    }
    /// <summary>
    /// Для сохранения блоков
    /// </summary>
    void SaveBlocks()
    {
        //получаем все блоки на сцене
        GameObject[] allBlocks = GameObject.FindGameObjectsWithTag("Block");
        string saveStr = "";
        //берем каждый блок
        foreach (GameObject g in allBlocks)
        {
            //позиция блока
            Vector3 pos = g.transform.position;
            //записываем информацию о блоке в строку.
            saveStr += string.Format("{0}#{1}#{2}#{3};", pos.x, pos.y, pos.z, GetIdByMat(g.renderer.sharedMaterial));
        }
        //добавляем строку с блоками в хронилище
        PlayerPrefs.SetString("blocks", saveStr);
        //сохраняем!!!
        PlayerPrefs.Save();

        Debug.Log(string.Format("Сохранено {0} блоков", allBlocks.Length));
    }
    /// <summary>
    /// Возвращает ИД указанного материала
    /// </summary>
    /// <param name="m"></param>
    /// <returns></returns>
    byte GetIdByMat(Material m){
        switch (m.name)
        {
            case "mBlue":
                return 0;
            case "mRed":
                return 1;
             case "mNew"://добавили материал
                return 2;
            default:
                return 0;
        }
    }
    /// <summary>
    /// Возвращает Материал по ИД
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    Material GetMatById(byte id)
    {
        switch (id)
        {
            case 0:
                return mat_blue;
            case 1:
                return mat_red;
            case 2://и вот тут
                return new_mat;
            default:
                return mat_blue;
        }
    }
}
avatar
Здравствуйте, подскажите а как можно сделать что бы когда я выбирал блоки там все было по категориям?
avatar
Посмотри что такое NGUI

С помощью нее можно содать окошко красивое и разбить на категории
avatar
а вы есть в контакте? А то тут не удобно писать.
avatar
Здравствуйте, а как мне добавить в скрипт новый материал и переименовать эти red и blue, и ещё не могли бы сказать как сделать, чтобы plane состоял из блоков которые можно ломать?
avatar
кстати, будет продолжение?
avatar
Ребят, ну что вы в самом деле. В уроке же всё подробно разжовано, специально для таких как мы :) Смотрите внимательно и вникайте.Чтобы добавить материал, нужно добавить материал: public Material mat_red; Чтобы переименовать материал, нужно его переименовать: public Material Название;(тогда при создании материала в Юнити, его нужно назвать точно также: «Название». Остальное по аналогии: всё что сделано в коде с mat_Red, тожесамое делаем и со своим новым материалом.Только подставляем своё название «Название».
if (GUILayout.Button(«Red»)) //Если нажата кнопка «Название»
{
block.renderer.sharedMaterial = mat_red; //Создаём блок с материалом = Название;
}

А вот урок по генерации плоскости из кубиков был бы действительно очень актуален :)
afrokick, может порадуете нас таким уроком?
avatar
ПОМОГИТЕ КТО-НИБУДЬ! У меня такая проблема — я сделал все также как на видео, все работало. Но, когда я добавил еще один блок, и еще пару своих усовершенствований + свой скрипт с генерацией карты и респавном при падении у меня при сохранении все кубики распознавались как default и нельзя было сохранить 2 кубика с разными раскрасками, то есть при повторном заходе все становилось одним цветом. С чем может быть связана данная проблема?
avatar
Мне тоже нужна помощь. Поворачиваю объекты этим кодом. А что нужно добавить в «void SaveBlocks()» и «void LoadBlocks()» чтобы угол поворота объекта сохранялся и загружался?
код:
var rotationSpeed = 50.0;

function Update()
{
var hit: RaycastHit;
var ray: Ray = Camera.mainCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));

if (Physics.Raycast (ray, hit, 100.0) && hit.collider.gameObject.tag == «Container»)
{
if (Input.GetKey (KeyCode.LeftArrow))
{
var ydir = Input.GetAxis(«Horizontal»);
hit.transform.Rotate(0,ydir * rotationSpeed * Time.deltaTime,0);
}
if (Input.GetKey (KeyCode.RightArrow))
{
var ydir1 = Input.GetAxis(«Horizontal»);
hit.transform.Rotate( 0,ydir1 * rotationSpeed * Time.deltaTime ,0);
}
if (Input.GetKey (KeyCode.UpArrow))
{
var ydir2 = Input.GetAxis(«Vertical»);
hit.transform.Rotate( ydir2 * rotationSpeed * Time.deltaTime,0,0);
}
if (Input.GetKey (KeyCode.DownArrow))
{
var ydir3 = Input.GetAxis(«Vertical»);
hit.transform.Rotate( ydir3 * rotationSpeed * Time.deltaTime,0,0);
}
}
}
avatar
hit.transform.eulerAngles — возвратит Vector3, в котроом x y z — это углы поворота, вот их и сохраняй.

Когда загрузишь, просто назначь новый поворот объекту с помощью hit.transform.eulerAngles = new Vector3(x,y,z);
avatar
anton_vas, на ваш вопрос невозможно ответить. Мы же не знаем что там у вас в игре понасовано. Попробуйте в инспекторе снимать галочки по очереди с тех скриптов, которые были добавлены. Без какого скрипта станет работать, значит в этом скрипте и ищите проблему.
avatar
Спасибо, я уже сам решил проблему. Просто была добавлена лишняя анимация при создании блока на сцене.
avatar
Skyden, спасибо за подсказку, но у меня не получается ей воспользоваться. Никак не пойму как это применить на практике. Может найдёте пару минут, добавите в этот код, чего там не хватает. Надеюсь, я не слишком многого прошу :) Для вас это пустячное дело, а мне будет урок и наглядный пример на всю оставшуюся жизнь!
код:
void SaveBlocks()
{
GameObject[] allBlocks = GameObject.FindGameObjectsWithTag(«Block»);
string saveStr = "";
foreach (GameObject g in allBlocks)
{
Vector3 pos = g.transform.position;
saveStr += string.Format("{0}#{1}#{2}#{3};", pos.x, pos.y, pos.z, GetIdByMat(mat_container));
}
PlayerPrefs.SetString(«blocks», saveStr);
PlayerPrefs.Save();
}
void LoadBlocks()
{
if (!PlayerPrefs.HasKey(«blocks»))
return;
string strBlocks = PlayerPrefs.GetString(«blocks»);
string[] masBlocks = strBlocks.Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);
foreach (string s in masBlocks)
{
string[] masParam = s.Split(new char[] { '#' }, System.StringSplitOptions.RemoveEmptyEntries);
Vector3 pos = new Vector3(float.Parse(masParam[0]), float.Parse(masParam[1]), float.Parse(masParam[2]));
Instantiate(block, pos, Quaternion.identity);
}
}
//(ID материала не нужно, у меня модели)
avatar
Сделал как по уроку. Теперь встала задача. Как сделать так чтобы было видно блок который ставишь?
И еще как отчистить поле от блоков? Ну вроде начать новую игру.
avatar
Да и нужно сделать чтобы при выборе блока было видно картинку как это сделать?
avatar
Новую игру можно так: Создаём новую сцену «Menu» и в ней на объект вешаем скрипт:
using UnityEngine;
using System.Collections;
public class Menu: MonoBehaviour {
void OnGUI(){
if(GUI.Button(new Rect((Screen.width / 2)- 25, (Screen.height / 2)- 60, 100,30), «Continue»))
{
Application.LoadLevel(«Game»); // Переходим в сцену «Game»
}
if(GUI.Button(new Rect((Screen.width / 2)- 25, (Screen.height / 2)- 28, 100,30), «NEW GAME»))
{
PlayerPrefs.DeleteAll(); // Очищаем Player Prefs
Application.LoadLevel(«Game»); // Переходим в сцену «Game»
}
}
}
avatar
Что значит «чтобы было видно картинку»? Если создание инвентаря, то в инете есть уроки. Здесь выше давали ссылку. Ну а если по простому, то вот:
public Texture2D Имя_текстуры;

if(GUI.Button(new Rect((Screen.width / 2)- 250, (Screen.height / 2)- 255, 50,50), Имя_текстуры))
{
block.renderer.sharedMaterial = mat_blue;
}

Меняем в коде из урока, кнопку с текстом, на кнопку с картинкой.
Screen.width / 2 — это нужно, чтобы на разных разрешениях мониторов кнопка не меняла своё местоположение.
avatar
"-Чтобы было видно блок, который ставишь"?
Может нужна подсветка объекта? В Майнкрафте выделяется блок, на который поставится следующий. Это нужно?
avatar
За эти 2 совета выше

"-Чтобы было видно блок, который ставишь"
Мне нужно чтобы когда запускаешь в верхней части экрана было окно в котором была бы текстура блока который ставишь.

«Может нужна подсветка объекта? В Майнкрафте выделяется блок, на который поставится следующий. Это нужно?»

Да это тоже нужно.

Заранее спасибо
avatar
Да и еще одно самое главное как сделать так чтобы мышь воздействовала только на игру. Просто когда например осматриваюсь в игре и нажимаю поставить блок. Открывается пуск и другие программы так как это исправить?
avatar
Привязка курсора к центру экрана:
void Start(){
Screen.showCursor = false; //показать курсор = ложно
Screen.lockCursor = true; //курсор в центре экрана = истинно
}
А при нажатии кнопки «Инвентарь», делаешь наоборот. Отвязываешь курсор от центра и делаешь видимым, чтобы блоки выбирать.
— Смена GUI-текстуры:
public Texture2D TexD;
public Texture2D TexStone1;
void OnGUI(){
GUI.DrawTexture(new Rect (Screen.width — 155,Screen.height — 105,140,90), TexD);

if(GUI.Button(new Rect((Screen.width / 2)- 250, (Screen.height / 2)- 255, 50,50), stone1)){
TexD = TexStone1;
}
}
avatar
У меня ошибку выдает
avatar
GUI.DrawTexture(new Rect (Screen.width — 155,Screen.height — 105,140,90), TexD);
Здесь минусы почему-то длинными получились, замените вручную: — 155 и — 105.
Или всю строку вручную. Выделение объекта у меня есть, скачал в интернете, только там надо дистанцию до объекта добавить, ну и потестить что к чему.Попозже выложу, если всё получится, а то я же сам новичёк :)
avatar
Тем, кто мне в личке спрашивал подсветку объекта, пишу здесь, может ещё кому пригодится.
Если хотите подсветку в своей игре, нужно изменить код из урока:
Создать префаб MyBlockBlue, с тегом BlockBlue, с материалом mat_Blue.Создать префаб MyBlockRed,c тегом BlockRed, с материалом mat_Red.
код:
/*
Author: afrokick /edited unknown
Forum: www.blog.devby.ru
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Controller: MonoBehaviour{

public GameObject blockblue;
public GameObject blockred;
public Material mat_blue;
public Material mat_red;
bool goblockblue = true;
bool goblockred;

void Start(){
LoadBlocks();
Screen.showCursor = false;
Screen.lockCursor = true;//привязываем курсор к центру экрана
}
void Update(){
Ray ray = Camera.mainCamera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 10f) && hit.collider.CompareTag(«BlockBlue»)
|| Physics.Raycast(ray, out hit, 10f) && hit.collider.CompareTag(«BlockRed»))
// если луч сталкивается с объектами под тегом BlockBlue и BlockRed, то…
{
if (Input.GetMouseButtonUp(0)) //… если нажата левая мышь…
{
if (goblockblue) //… если разрешено создание синего блока…
{ Vector3 pos = hit.collider.transform.position;
pos += hit.normal;
Instantiate(blockblue, pos, Quaternion.identity);//… то создаём синий,
}
if (goblockred) // если разрешено создание красного блока…
{ Vector3 pos = hit.collider.transform.position;
pos += hit.normal;
Instantiate(blockred, pos, Quaternion.identity);//… то создаём красный.
}
}
else if (Input.GetMouseButtonUp(1))
{
DestroyObject(hit.collider.gameObject);
}
}
else if (Physics.Raycast(ray, out hit, 10f) && hit.collider.name.Equals(«Plane»))
{
if (Input.GetMouseButtonUp(0))
{
if (goblockblue)
{ Vector3 pos = hit.point;
pos.y = 0;
pos.x = Mathf.Round(pos.x);
pos.z = Mathf.Round(pos.z);
Instantiate(blockblue, pos, Quaternion.identity);
}
if (goblockred)
{ Vector3 pos = hit.point;
pos.y = 0;
pos.x = Mathf.Round(pos.x);
pos.z = Mathf.Round(pos.z);
Instantiate(blockred, pos, Quaternion.identity);
}
}
}
}
void OnGUI()
{
if (Input.GetKey(KeyCode.M))
{ Screen.showCursor = true;
Screen.lockCursor = false;
GUILayout.BeginVertical();
if (GUILayout.Button(«Blue»)) //если нажата кнопка «Blue»
{
goblockblue = true; // разрешаем создание синего блока
goblockred = false; // запрещаем создание красного
}
if (GUILayout.Button(«Red»)) // если нажата кнопка «Red»
{
goblockblue = false; // запрещаем создание синего блока
goblockred = true; // разрешаем создание красного
}
GUILayout.EndVertical();
}
else{
Screen.showCursor = false;
Screen.lockCursor = true;
}
}
void OnApplicationQuit(){
SaveBlocks();
}
/// /// Для загрузки блоков
///
void LoadBlocks()
{ if (!PlayerPrefs.HasKey(«blocks1»))
return;
if (!PlayerPrefs.HasKey(«blocks2»))
return;
string strBlocks1 = PlayerPrefs.GetString(«blocks1»);
string strBlocks2 = PlayerPrefs.GetString(«blocks2»);
string[] masBlocks1 = strBlocks1.Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);
string[] masBlocks2 = strBlocks2.Split(new char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);
foreach (string s in masBlocks1)
{ string[] masParam1 = s.Split(new char[] { '#' }, System.StringSplitOptions.RemoveEmptyEntries);
Vector3 pos = new Vector3(float.Parse(masParam1[0]), float.Parse(masParam1[1]), float.Parse(masParam1[2]));
Instantiate(blockblue, pos, Quaternion.identity);
}
foreach (string s in masBlocks2)
{ string[] masParam2 = s.Split(new char[] { '#' }, System.StringSplitOptions.RemoveEmptyEntries);
Vector3 pos = new Vector3(float.Parse(masParam2[0]), float.Parse(masParam2[1]), float.Parse(masParam2[2]));
Instantiate(blockred, pos, Quaternion.identity);
}
}
void SaveBlocks()
{ GameObject[] allBlocks1 = GameObject.FindGameObjectsWithTag(«BlockBlue»);//1 — синий
GameObject[] allBlocks2 = GameObject.FindGameObjectsWithTag(«BlockRed»);//2 — красный
string saveStr1 = "";
string saveStr2 = "";
foreach (GameObject g in allBlocks1)
{ Vector3 pos = g.transform.position;
saveStr1 += string.Format("{0}#{1}#{2}#{3};", pos.x, pos.y, pos.z,(mat_blue));
}
PlayerPrefs.SetString(«blocks1», saveStr1);
PlayerPrefs.Save();
foreach (GameObject g in allBlocks2)
{ Vector3 pos = g.transform.position;
saveStr2 += string.Format("{0}#{1}#{2}#{3};", pos.x, pos.y, pos.z, (mat_red));
}
PlayerPrefs.SetString(«blocks2», saveStr2);
PlayerPrefs.Save();
}
}
=================================================================
Код выделения объекта цветом при наведении курсора.Повесить на объекты, которые нужно выделять.Цвет выбирается в инспекторе.

using UnityEngine;
using System.Collections;
public class SelectColor: MonoBehaviour{
public Color myColor;
Color OriginalColor;
void Start(){
OriginalColor = renderer.material.color;
}
void OnMouseEnter (){
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 10f)){
renderer.material.color = myColor;
}
}
void OnMouseExit (){
renderer.material.color = OriginalColor;
}
}
avatar
при попытке переместить MineCraftController в plane то вылазит такая ошибка.
avatar
Подскажите пжл, как сделать что бы карта сама генерировалась и состояла из кубов?
avatar
*Генерировалась рандомно
avatar
Есть на сайтах такой код для генерации из кубиков. Только большую карту не создашь, лагать будет. Такие вещи делаются не из кубиков, а из чанков, для новичка это довольно сложный процесс.

using UnityEngine;
using System.Collections;

public class PlaneGenerator: MonoBehaviour {

public Transform prefab;//Создаем ячейку для префаба

void Awake () {
for(int x = 0; x < 10; x++) { //Сколько кубиков будет по x(ширина либо длина, решать вам)
for(int y = 0; y < 10; y++) { //Сколько кубиков по y(высота)
for(int z = 0; z < 10; z++) { //Сколько кубиков по z (ширина либо длина, решать тоже вам)
Instantiate(prefab, new Vector3 (x,y,z),Quaternion.identity); // Ну и создание этих кубиков
}
}
}
}
}
avatar
Я хочув скрипте сделать так вот чтобы можно было ставить блоки и сфру как можно сделать скажите плиизззз, дайте скрипт плииззз.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.