С того времени, когда я начал рассматривать Blender не как мощный инструмент 3D моделирования, а как среду программирования, меня интересовал вопрос управления в виртуальном мире.
В предыдущих постах я показывал, как решать совершенно не стандартные для Blender задачи.
Итак, хоть я скрытый злодей, помышляющий о том, как завоевать вселенную, она мне не нужна, как и власть и деньги, хотя без денег на «железо» и интернет не обойтись, мной больше двигают исследовательские цели. Ну, скажите, какой смысл от мира, если его нельзя пощупать и поизучать? На мой взгляд – никакого. Поэтому, создав виртуальный мир, мне стало интересно, а как же все-таки в него пустить меня, исследователя?
Решение простое и одно – надо писать скрипт и запустить его в Blendr. Скрипт управления камерой. Возиться самому мне в ту пору, естественно, не хотелось. Я только представил все эти аффинные преобразования да еще в трех мерном мире, мне сразу плохо стало. Другой математической модели управления камерой тогда я не видел. И перспектива возиться с матрицами меня, прямо скажу, очень сильно, тогда еще студента, угнетала. Но ведь к тому времени на Blender уже писались игры, а, значит, управление камерой было реализовано. Значит, задача сводится к нахождению удовлетворительного и, по возможности, универсального скрипта управления камерой. Несколько вариантов с преобразованиями матриц я отмел, как меня не устраивающие, и стал искать дальше.
Все же странно устроен человек, не представляя, как это можно сделать иначе, отметает варианты и ищет, уж поистине то, не знаю что. Но, самое интересное, в людском мире то, что это «не знаю что» находится. Удовлетворивший меня скрипт находится на www.tutorialforblender3D.com, но так же файл с этим же скриптом я выкладываю здесь. В тексте ничего не меняю, считаю, что не имею на это право. А вот здесь объясню механизм его работы.
Считается одной из самых сложных задач по обучению программирования – перевод текста программы на человеческий язык, то есть словами объяснить алгоритм работы Вашей программы. Лично я не люблю взять готовый скрипт и использовать его, не разобравшись в механизмах его работы, если, что-то не понял, то изучаю этот скрипт до дыр. Но для того, чтобы понять работу скрипта управления логикой, нужно понимать логику управления логическими блоками (считайте это каламбуром, а не тавтологией). Про работу логических блоков я объяснять не стану (в обозримом будущем выйдет моя статья по созданию игр в Blender, а повторяться, я не люблю – если возникнет необходимость что-то уточнить, можно задать вопрос и посмотреть на демонстративный файл).

На рисунке продемонстрированы все необходимые настройки логических блоков:
Сенсер одни – Mouse, он настроен на событие Movement, контроллер тоже одни, в нем находится наш скрипт, управления камерой. А вот актуаторов – 2: одни, LookLeftRight, отвечает за движения камеры по горизонтали, второй, LookUpDown, - по вертикали.
Условно я делю скрипт на две части: get и set части. В первой части мы объясняем скрипку откуда он берет исходные данные и что с ними делает, во второй части присваиваем полученные результаты – все как всегда просто:
# импортируем библиотекуt Rasterizer
import Rasterizer
# для удобства чтения скрипта вводим переменную, которой присваиваем текущий
# контроллер
controller = GameLogic.getCurrentController()
# назначаем переменную, к которой этот скрипт присоединяем
player = controller.getOwner()
# присваиваем переменной сенсор с именем Mouse
#здесь имеется ввиду то имя, которым Вы назвали сенсор в логических блоках
mouse = controller.getSensor("Mouse")
# вводим переменные, которым присваиваем наши актуаторы
lookLeftRight = controller.getActuator("LookLeftRight")
lookUpDown = controller.getActuator("LookUpDown")
В этом мы связали входящие данные и выходящие, на мой взгляд, именно эта связь является самой трудной для понимания: тут происходит основная связь скрипта с логикой самого файла – если скрипт универсальный, то файл надо подстраивать под этот скрипт, вот для это на и назначаются все переменные, но идем дальше.
# назначаем переменным ширину и высоту экрана, это надо для перемещения
width = Rasterizer.getWindowWidth()
height = Rasterizer.getWindowHeight()
# определяем mouse movement функцию
def mouseMove():
# определяем расстояние, пройденное от центра экрана
x = width/2 - mouse.getXPosition()
y = height/2 - mouse.getYPosition()
# инициализируем mouse если еще не сделали этого
if hasattr(player, 'mouseInit') == False:
x = 0
y = 0
# тут баг
# и вместо True. надоиспользовать 1
player.mouseInit = 1
# возвращаем передвижение мыши
return (x, y)
# присваиваем mouse значения, полученные функцией, их два X,Y
move = mouseMove()
# задаем чувствительность
sensitivity = 0.001
# Суммируем направление и чувствительность
#на самом деле умножаем, но оставил термин из комментария к скрипту
# move[0] – это перемещение мыши по X
# move[1] – это перемещение мыши по Y
leftRight = move[0] * sensitivity
upDown = move[1] * sensitivity
# устанавливаем, полученные значения в актуаторы
lookLeftRight.setDRot( 0.0, 0.0, leftRight, False)
lookUpDown.setDRot( upDown, 0.0, 0.0, True)
# используем, уже полученные актуаторы в нашем файле
GameLogic.addActiveActuator(lookLeftRight, True)
GameLogic.addActiveActuator(lookUpDown, True)
# размещаем mouse в центре экрана
Rasterizer.setMousePosition(width/2, height/2)
Вот и все – скрипт работает, можете проверять.
Это один из лучших скриптов для управления камерой при создании игр, у меня он лежит в качестве боевого скрипта.
Желаю Вам успехов.